Unix 域套接字绑定在 windows 中失败
Unix domain socket bind failed in windows
我运行下面的代码是为了创建 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 domain socket 是在 windows10 几年前引入的,我正在使用最新版本,因此应该支持它。知道我的代码有什么问题吗?
编辑:我发现在基于 linux 的机器中,我将以下 sockaddr 传递给 ::bind
(const boost::asio::detail::socket_addr_type) *addr = (sa_len = '[=12=]', 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
字段。
谢谢
问题似乎是 SO_REUSEADDR
套接字选项,这是 ASIO 默认设置的。设置此选项本身会成功,但会导致后续 bind
失败。
用reuse_addr
= false
构造acceptor,那么应该绑定成功:
local::stream_protocol::acceptor acceptor(my_io_context, server, false);
我运行下面的代码是为了创建 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 domain socket 是在 windows10 几年前引入的,我正在使用最新版本,因此应该支持它。知道我的代码有什么问题吗?
编辑:我发现在基于 linux 的机器中,我将以下 sockaddr 传递给 ::bind
(const boost::asio::detail::socket_addr_type) *addr = (sa_len = '[=12=]', 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
字段。
谢谢
问题似乎是 SO_REUSEADDR
套接字选项,这是 ASIO 默认设置的。设置此选项本身会成功,但会导致后续 bind
失败。
用reuse_addr
= false
构造acceptor,那么应该绑定成功:
local::stream_protocol::acceptor acceptor(my_io_context, server, false);