c++ - boost asio 打开更多的一个套接字

标签 c++ sockets boost boost-asio

我是 boost::asio 的初学者。我有使用 boost::asio::ip::tcp::socket 的客户端和服务器。当我使用一个 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() 有助于避免问题。

最佳答案

您使用阻塞套接字。这意味着您的服务器在客户端连接到端口 1950 之前不会开始监听端口 1960。现在您有一个竞争条件,有时客户端比服务器快并在服务器尚未监听时尝试连接。

可能的解决方案:

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

关于c++ - boost asio 打开更多的一个套接字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51199884/

相关文章:

c++ - 每个结构只允许一个没有大小的数组?

c++ - 在编译时计算第 n 个素数

sockets - 使用 Java 发送零数据 TCP/IP 数据包

sockets - 如何告诉 TCP 服务器特定消息已经结束?

c++ - 为 cmake 生成的 eclipse 项目链接 boost::program_options 和 Armadillo 之间的错误

c++ - 适用于8位MCU的更快的16位乘法算法

c++ - 使用现代编译器的 C++ 中的 "memset"功能状态

c - 0 在 socket() 系统调用中表示什么?

c++ - 来自大量人口的随机样本陷入无限循环

c++ - boost 图形库 : deterministic order of iteration of in_edges?