首页 > 解决方案 > C++ boost 1.72 在 tcp::socket 上重新连接,在 Linux 上抛出 WSAEADDRINUSE 异常,但在 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 操作系统上遇到了如上所述的异常。

这是关闭套接字代码。

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

delete pClientSocket;

pClientSocket= nullptr;

标签: c++linuxsocketsboost

解决方案


尝试使用重用选项:

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

更新:

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

对于客户端套接字,这不太常见,您必须通过在套接字中调用 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);

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

另一方面,这段代码:

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) { }

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


推荐阅读