Портирование Winsock на сокеты Linux

У меня есть программа, которая работает с сетью с помощью Winsock, и одно из наших требований прямо сейчас — перенести нашу программу на Linux. Единственное, что нам мешает это сделать, это Winsock.

Мой вопрос: насколько легко я могу перенести это на реализацию Linux?

Есть ли какие-то подводные камни, о которых я должен знать, и если я просто включу соответствующие заголовочные файлы, с какими вещами я должен справиться?

Спасибо за любую помощь!

Я бы отправил код, но, к сожалению, не могу по юридическим причинам. Но наш код использует следующее:

WSAStartup(..)
WSACleanup(..)
Socket(..)
sendto(..)
recvfrom(..)
ioctlsocket(..)
setsocketopt(..)

person Mike Bailey    schedule 06.01.2011    source источник


Ответы (4)


Это будет зависеть от того, используете ли вы какие-либо специфичные для Windows сетевые функции или просто используете в основном API, совместимый с BSD.

Таким образом, если вы используете перекрывающиеся порты ввода-вывода и завершения ввода-вывода и другие расширенные части Winsock API, тогда будет очень сложно портировать, а если вы просто используете совместимый с BSD материал, тогда должно быть легко напишите тонкий слой перевода или даже просто включите запуск и завершение работы winsock внутри специфичного для Windows ifdef...

Это может помочь: http://tangentsoft.net/wskfaq/articles/bsd-compatibility.html

person Len Holgate    schedule 06.01.2011

Основываясь на этом списке функций, все должно более или менее просто работать. Добавьте #if _WIN32 вокруг вызовов WSAStartup и WSACleanup (аналог linux — ничего не делать, библиотека сокетов инициализируется автоматически).

Вам также может понадобиться некоторый код, зависящий от ОС, при настройке параметров сокета, некоторые из них одинаковы, некоторые нет, а типы могут быть разными.

person Ben Voigt    schedule 06.01.2011

Единственными вызовами, затрудняющими перенос, являются вызовы WSA*.

WSAStartup() -> nop WSACleanup() -> nop

Сокет/setsockopt -> сокет/setsockopt

В * nix сокеты блокируются по умолчанию, и нет необходимости или возможности использовать этот странный вызов setsockopt, чтобы возиться с ним.

иоктлсокет -> иоктл

В *nix мы не очень любим асинхронные сокеты и предпочитаем использовать системный вызов select().

---- Остальная часть этого ответа, похоже, применима только к winsock, совместимому с Win95 ----

К сожалению, поскольку оригинальный socket() в Winsock в некоторых случаях был сломан, вы, вероятно, использовали WSASocket() и поэтому должны преобразовать эти вызовы.

person Joshua    schedule 06.01.2011
comment
В нашем коде используется socket(), я указал, какие функции используются в коде, так как я не могу опубликовать фактический код. - person Mike Bailey; 06.01.2011
comment
с блокировкой не повозишься? В сокетах можно выполнять неблокирующий ввод-вывод, установив флаг O_NONBLOCK в файле сокета. дескриптор с использованием fcntl(2). Вы правы, хотя это другая функция, а не setsockopt. - person Ben Voigt; 07.01.2011
comment
Бен Войт: точно. Вызов windowsetsockopt вызывается для дескриптора NULL и устанавливает режим для всех новых сокетов. - person Joshua; 07.01.2011
comment
Я никогда не вызывал setsockopt для дескриптора NULL. Где задокументировано такое поведение? - person Ben Voigt; 07.01.2011
comment
Забавно, я больше не могу найти документацию в Интернете. Может быть, потому что я все еще использовал Win9x-совместимый номер версии winsock при инициализации, поэтому у него было забавное поведение. - person Joshua; 07.01.2011
comment
Чтение справочника MSDN Winsock (msdn.microsoft.com/en-us/library/windows/desktop/) не наводит меня на мысль, что Windows и Linux по-разному относятся к блокирующим сокетам. - person pattivacek; 10.07.2013

Не видя кода, трудно сказать, насколько это просто. Но вы должны иметь возможность заменить вызовы winsock на аналоги в sys/socket.h.

person hometoast    schedule 06.01.2011