#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. Это приходит с опытом 🙂 Когда что-то, что должно работать, не работает, попробуйте отключить ненужные опции.