I'm running the following code in order to create listener to unix domain socket.
Under macOS this code is working fine, but in Windows it produces the following error from the tcp_acceptor command : WSAEOPNOTSUPP
Here's a minimal reproducible example :
#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;
}
While debugging inside the boost library, i saw that the failure comes from the internal bind in the following code :
and this is the frame variables (it's clearly visible that sa_family = AF_UNIX (1):
I know that unix domain socket was introduced in windows10 few years ago, and i'm working with the latest version so it should be supported. Any idea what's wrong in my code?
EDIT : I've found out that in linux based machine I pass the following sockaddr to ::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..............```
and in windows i get a slightly different struct :
{sa_family=1 sa_data=0x000000fffd33f682 "C:\\temp\\UnixSo... }const sockaddr *
Notice that the len
field is missing in the windows platform.
Thanks
The issue seems to be the SO_REUSEADDR
socket option, which ASIO by default sets. Setting this option itself succeeds, but causes the subsequent bind
to fail.
Construct the acceptor with reuse_addr
= false
, then the binding should succeed:
local::stream_protocol::acceptor acceptor(my_io_context, server, false);