【问题标题】:C++ boost 1.72 reconnect on tcp::socket throwing an exception with WSAEADDRINUSE on linux, but works on WindowsC++ boost 1.72 在 tcp::socket 上重新连接,在 Linux 上抛出 WSAEADDRINUSE 异常,但在 Windows 上有效
【发布时间】:2021-11-24 20:26:41
【问题描述】:

您好,我的代码在 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;

【问题讨论】:

  • 我不知道 boost 接口但是 socket() 有一个标志 SO_REUSEADDR 如果在 boost 中有一个等效的标志你可以试试?
  • 否则,您可能只需要给系统一点时间来关闭它在该套接字上打开的所有连接,然后才能重用该端口。

标签: c++ linux sockets boost


【解决方案1】:

尝试使用重用选项:

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);

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

【讨论】:

  • 我正在使用这样的代码,但它不起作用。 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) { }
  • 是的!你说的对。我应该在我的回答中注意到这一点,顺便说一句:-)
猜你喜欢
  • 1970-01-01
  • 2019-10-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多