【问题标题】:Unix domain socket bind failed in windowsUnix域套接字绑定在Windows中失败
【发布时间】:2025-12-19 19:50:07
【问题描述】:

我正在运行以下代码来创建 unix 域套接字的侦听器。 在 macOS 下,此代码运行良好,但在 Windows 中,它会从 tcp_acceptor 命令产生以下错误:WSAEOPNOTSUPP

这是一个最小的可重现示例:

#include <iostream>
#include <boost/asio/local/stream_protocol.hpp>
constexpr char* kFileName = "file.sock";
using namespace std;
using namespace boost::asio;

int main(int argc, char* argv[])
{
    io_context my_io_context;
    ::_unlink(kFileName); // Remove previous binding.
    local::stream_protocol::endpoint server(kFileName);
    local::stream_protocol::acceptor acceptor(my_io_context, server);
    local::stream_protocol::socket socket(my_io_context);
    acceptor.accept(socket);
    return 0;
}

在 boost 库中调试时,我看到失败来自以下代码中的内部绑定:

这是帧变量(很明显 sa_family = AF_UNIX (1):

我知道unix域套接字是几年前在windows10中引入的,我正在使用最新版本,所以应该支持它。知道我的代码有什么问题吗?

编辑:我发现在基于 linux 的机器中,我将以下 sockaddr 传递给 ::bind

(const boost::asio::detail::socket_addr_type) *addr = (sa_len = '\0', sa_family = '\x01', sa_data = "/tmp/server.sock")
(lldb) memory read addr
0x7ffeefbffa00: 00 01 2f 74 6d 70 2f 73 65 72 76 65 72 2e 73 6f  ../tmp/server.so
0x7ffeefbffa10: 63 6b 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ck..............```

在 windows 中我得到一个稍微不同的结构:

{sa_family=1 sa_data=0x000000fffd33f682 "C:\\temp\\UnixSo... }const sockaddr *

请注意,Windows 平台中缺少 len 字段。

谢谢

【问题讨论】:

  • 为什么要在windows上安装这样的socket?
  • @MichaelChourdakis,我想创建一个跨平台的 ipc 服务。 Windows 应该支持它 (devblogs.microsoft.com/commandline/af_unix-comes-to-windows)
  • “应该支持”你检查sc query afunix了吗?
  • @n.1.8e9-where's-my-sharem.,我的状态正在运行。
  • 你在浪费时间。 Windows 具有文件映射,这是首选的 IPC 机制。对于不需要互操作的东西,无需跨平台。一般来说,可能是可移植的 Linux 东西在 Windows 上不能很好地工作,而 Windows 开发人员也不会为这些东西烦恼。

标签: c++ boost cross-platform boost-asio unix-socket


【解决方案1】:

问题似乎是 ASIO 默认设置的SO_REUSEADDR 套接字选项。设置此选项本身会成功,但会导致后续的bind 失败。

reuse_addr = false构造acceptor,那么绑定应该成功:

  local::stream_protocol::acceptor acceptor(my_io_context, server, false);

【讨论】:

  • 看起来不错。顺便说一句,我在 Windows 上找不到任何关于此标志不支持的官方 Microsoft 文档......你是怎么想出来的?
  • 它带有经验 :-) 当应该工作的东西不起作用时,请尝试禁用不必要的选项。