BOOST ASIO:为啥我在 Windows 中没有得到“绑定:地址已在使用”(但在 Linux 中得到它)?

Posted

技术标签:

【中文标题】BOOST ASIO:为啥我在 Windows 中没有得到“绑定:地址已在使用”(但在 Linux 中得到它)?【英文标题】:BOOST ASIO: Why don't I get "bind: Address already in use" in Windows (but do get it in Linux)?BOOST ASIO:为什么我在 Windows 中没有得到“绑定:地址已在使用”(但在 Linux 中得到它)? 【发布时间】:2011-08-23 17:11:14 【问题描述】:

尝试绑定已经绑定的 TCP 端口会引发异常(“绑定:地址已在使用”异常)。

它确实发生在 Linux 下。但在 Windows 下,不会引发任何异常..

可能是因为在 windows 下它试图绑定到任何接口?但在 Linux 中,它会尝试绑定到所有这些,如果不是所有这些都被绑定,则会引发异常?

这里是sn-p的代码:

    try 
        tcp::endpoint endpoint(tcp::v4(), 8081);
        tcp::acceptor acceptor(io_service);
        acceptor.open(endpoint.protocol());
        acceptor.set_option(tcp::acceptor::reuse_address(true));
        acceptor.set_option(tcp::acceptor::enable_connection_aborted(true));
        acceptor.bind(endpoint);
        acceptor.listen(1024)
    catch(std::exception &e) 
         cout << e.what() << endl;
    

【问题讨论】:

【参考方案1】:

在 Windows 中,选项tcp::acceptor::reuse_address 等效于调用setsockopt 并指定SO_REUSEADDR。这特别允许多个套接字绑定到一个地址,即使它正在使用中。请参阅 MSDN 文档here.

在 Win32 (SO_EXCLUSIVEADDRUSE) 中有一个对应的选项是 documented here。这篇文章详细介绍了在 Win32 平台上简单地使用 SO_REUSEADDR 的一些潜在缺点。

【讨论】:

谢谢。这就解释了。唉,我在 ASiO 中找不到对应的 SO_EXCLUSIVEADDRUSE 标志。所以我想唯一的选择是包含 winsock.h 并直接设置这个标志。 是的,我发现 boost::asio 中缺少一些功能,这是一个,另一个是 IGMPv3 多播支持。在这两种情况下,您都必须使用本机套接字和 setsockopt 函数。 有点晚了,但你可以这样做:typedef boost::asio::detail::socket_option::boolean&lt;BOOST_ASIO_OS_DEF(SOL_SOCKET), SO_EXCLUSIVEADDRUSE&gt; excluse_address; acceptor.set_option(excluse_address(true));

以上是关于BOOST ASIO:为啥我在 Windows 中没有得到“绑定:地址已在使用”(但在 Linux 中得到它)?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 boost::asio::read 缓冲区数据大小小于读取大小?

为啥这个简单的 Boost::asio 程序不能按预期工作?

为啥这个 boost::asio::tcp::socket 可以重用?

Boost.ASIO 性能不佳

为啥 Boost.Asio SSL 请求返​​回 405 Not Allowed?

使用 boost::asio::thread_pool 的 C++ 线程池,为啥我不能重用我的线程?