C++ boost 1.72 在 tcp::socket 上重新连接,在 linux 上使用 WSAEADDRINUSE 抛出异常,但在 Windows 上有效

C++ boost 1.72 reconnect on tcp::socket throwing an exception with WSAEADDRINUSE on linux, but works on Windows

您好,我的代码在 windows 上运行正常,但在 linux 上,重新连接功能不起作用,它会抛出一个值 WSAEADDRINUSE 的异常。

pClientSocket = new tcp::socket(*pIO_context, tcp::endpoint(boost::asio::ip::make_address(127.0.0.1, 50001));

它第一次在 Windows 和 Linux 上工作,但是当我关闭套接字并尝试再次连接时,我只在 linux 上遇到如上所述的异常OS.

这里是关闭套接字的代码。

boost::system::error_code ec;
pClientSocket->shutdown( boost::asio::socket_base::shutdown_type::shutdown_receive, ec);
pClientSocket->close(eCode);

delete pClientSocket;

pClientSocket= nullptr;

尝试使用重用选项:

boost::asio::socket_base::reuse_address option(true);
socket.set_option(option);

更新:

这通常发生在您尝试将服务器套接字绑定到已在使用或最近使用过的地址(并且套接字仍在等待 OS 清理)。

对于客户端套接字,这种情况不太常见,您必须通过在套接字中调用 bind()- 来强制端口才能发生这种情况。

现在代码:

pClientSocket = new tcp::socket(*pIO_context, tcp::endpoint(boost::asio::ip::make_address(127.0.0.1, 50001)); 
boost::asio::socket_base::reuse_address option(true); 
socket.set_option(option);

调用this 构造函数重载。此构造函数创建套接字并尝试将其绑定到指定地址。它失败了,因为您没有机会指定重用选项。

另一方面,这段代码:

pClientSocket = new tcp::socket(*pIO_context); 
pClientSocket->open(boost::asio::ip::tcp::v4()); 
pClientSocket->set_option(socket_base::reuse_address(true));

boost::system::error_code ec; 
pClientSocket->bind(tcp::endpoint(make_address(127.0.0.1, 50001), ec); 
if (ec) { }

调用 this 构造函数重载,它只创建套接字但不打开或连接它。这允许在 bind/connect 之前指定任何套接字选项,等等