Search code examples
c++socketsboosttcpmingw-w64

boost.asio how to avoid two clients to connect same server at same port


my server code is as follows:

#include <bits/stdc++.h>
#include <boost/asio.hpp>
#include <boost/array.hpp>
#include <boost/asio/socket_base.hpp>
using namespace std;
using boost::asio::ip::tcp;
using namespace boost::asio;
using namespace boost;
int main(int argc, char* argv[])
{

    io_service iosev;
    ip::tcp::acceptor acceptor(iosev,
                               ip::tcp::endpoint(ip::tcp::v4(), 1000));

    for(;;)
    {
        
        ip::tcp::socket socket(iosev);


        acceptor.accept(socket);

        std::cout << socket.remote_endpoint().address() << std::endl;


        acceptor.bind(ip::tcp::endpoint(ip::tcp::v4(), 1000));

        boost::system::error_code ec;
        std::string message;
        while (std::cin>>message) {
            socket.write_some(buffer(message), ec);
            if (*(message.end()-1)=='@') break;
        }

        if(ec)
        {
            std::cout <<
                      boost::system::system_error(ec).what() << std::endl;
            break;
        }
    }

    return 0;
}

my client code is as follows:

#include <bits/stdc++.h>
#include <boost/asio.hpp>
#include <boost/array.hpp>
#include <boost/asio/socket_base.hpp>
using namespace std;
using boost::asio::ip::tcp;
using namespace boost::asio;
using namespace boost;
int main(){
    try
    {
        
        boost::asio::io_service io;
        tcp::socket socket(io);

        
        tcp::endpoint end_point(boost::asio::ip::address::from_string("127.0.0.1"), 1000);
        socket.connect(end_point);

        for (;;)
        {
            boost::array<char, 128> buf;
            boost::system::error_code error;

            
            size_t len = socket.read_some(boost::asio::buffer(buf), error);

            if (error == boost::asio::error::eof)
            {
                break;    //connection closed cleadly by peer
            }
            else if (error)
            {
                throw boost::system::system_error(error);    //some other error
            }

            cout.write(buf.data(), len);
            cout<<"\n";
        }
    }
    catch (std::exception& e)
    {
        cout<<e.what()<<endl;
    }
    std::system("pause");
}

If I run server once and open two clients which will set to connect "127.0.0.1:1000", the first opened client works correctly, but the second opened client cannot receive anything sent by server function write_some(...) and the second opened client doesn't get any errors (it seems like it always waits for something). Why? how can I change the programming codes to let client get errors/exceptions while connecting to a server:port which has been connected by another client?


Solution

  • Your server is handling the first connection when the second one comes in. Though the second connection is accepted by the network layers in the operating system your program isn't available to handle it.

    That is why network servers must be made so they can handle multiple requests at the same time, for example by creating a thread for each incoming connection so the main (listening) thread is ready to handle the next incoming connection.