提升asio打开更多的一个套接字

时间:2018-07-05 21:02:39

标签: c++ sockets boost boost-asio

我是boost :: asio的初学者。我有使用boost::asio::ip::tcp::socket的客户端和服务器。当我使用一个插座时,一切正常。 但是现在我需要再创建一个。有时它可以工作,但是通常我在第二个套接字connect期间遇到异常。

以下是客户端的简化代码:

boost::asio::io_service ios;
std::cout << "Connecting 1950\n";
mp_SocketReader = new SerializationSocket(host, "1950", ios);
std::cout << "Connecting 1960\n";
mp_SocketWriter = new SerializationSocket(host, "1960", ios);

在服务器端:

boost::asio::io_service ios;
SerializationSocket socketReader(1950, ios);
SerializationSocket socketWriter(1960, ios);

以及SerializationSocket代码的一部分:

class SerializationSocket {
    boost::asio::ip::tcp::socket *mp_Socket;

public:
    /* As client */
    SerializationSocket(std::string host, std::string port, boost::asio::io_service& ios) {
        mp_Socket = new boost::asio::ip::tcp::socket(ios);
        boost::asio::ip::tcp::resolver resolver(ios);
        boost::asio::ip::tcp::resolver::query query(host, port);
        boost::asio::ip::tcp::resolver::iterator iterator = resolver.resolve(query);
        std::cout << "Before connect\n";
        connect(*mp_Socket, iterator);
        std::cout << "After connect\n";
    }

    /* As server */
    SerializationSocket(int port, boost::asio::io_service& ios) {
        mp_Socket = new boost::asio::ip::tcp::socket(ios);
        boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), port);
        boost::asio::ip::tcp::acceptor acceptor(ios, endpoint);
        acceptor.accept(*mp_Socket);
    }
};

发生问题时的输出(在客户端):

Connecting 1950
Before connect
After connect
Connecting 1960
Before connect
terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::system::system_error> >'
  what():  connect: Connection refused
Aborted (core dumped)

这种行为的原因是什么?

更新:套接字连接之间的帮助sleep()很少,可以避免出现问题。

1 个答案:

答案 0 :(得分:1)

您使用阻止套接字。这意味着您的服务器在客户端连接到端口1950之前不会在端口1960上开始侦听。现在您处于竞争状态,有时客户端比服务器快,并且在服务器尚未侦听时尝试连接。

可能的解决方案:

  1. 至少在服务器端使用异步(非阻塞)套接字,因此您 可以同时开始聆听/接受它们。
  2. 阻止套接字,但接受两个线程上的连接
  3. 在服务器套接字构造函数中创建接受器,但将对accept的调用移至另一个方法,现在创建两个服务器套接字,然后在两个套接字上都调用accept。我对此不确定,不记得 Asio 是如何实现的,但是值得尝试,因为这是最简单的解决方案。