Ошибка привязки сокета домена Unix в Windows

#c #boost #cross-platform #boost-asio #unix-socket

Вопрос:

Я запускаю следующий код, чтобы создать прослушиватель для доменного сокета 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 = '', 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 *
 

Обратите len внимание, что в платформе Windows это поле отсутствует.

Спасибо

Комментарии:

1. Зачем вам такие розетки на Windows?

2. @MichaelChourdakis, я хочу создать кроссплатформенный ipc-сервис. Windows должна поддерживать это ( devblogs.microsoft.com/commandline/af_unix-comes-to-windows )

3. «должно быть поддержано» Вы проверили sc query afunix ?

4. @n.1.8e9-где-моя-доля., я управляю государством.

5. Вы напрасно тратите время. Windows имеет сопоставление файлов, которое является предпочтительным механизмом IPC. Не нужно быть кросс-платформенным для чего-то, с чем вам не нужно было бы взаимодействовать. Как правило, материалы Linux, которые предположительно являются портативными, плохо работают в Windows, и разработчики Windows не утруждают себя подобными вещами.

Ответ №1:

Проблема, похоже, в опции SO_REUSEADDR сокета, которую по умолчанию устанавливает ASIO. Установка этого параметра сама по себе завершается успешно, но приводит bind к сбою последующего.

Постройте акцептор с reuse_addr = false , тогда привязка должна быть успешной:

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

Комментарии:

1. Выглядит великолепно. Кстати, я не смог найти никакой официальной документации Microsoft об этом флаге, который не поддерживается в Windows … Как ты это выяснил ?

2. Это приходит с опытом 🙂 Когда что-то, что должно работать, не работает, попробуйте отключить ненужные опции.