Портативность Winsock 2 - PullRequest
6 голосов
/ 06 мая 2009

Я собираюсь разработать некоторые вещи, связанные с сокетами, на C ++ и хотел бы, чтобы программное обеспечение было как можно более переносимым между Windows и Linux с самого начала (сделать его переносимым позже сложно)

Я смотрел на разные библиотеки, есть одна для C ++ из alhem.net и, конечно, есть boost :: asio. boost :: asio выглядит очень многообещающе, но будет очень большой зависимостью для приложений такого маленького размера.

Стоит ли вообще писать материал самому или я должен просто использовать библиотеку? Если я сделаю это сам, какие будут главные подводные камни?

Ответы [ 6 ]

5 голосов
/ 15 июня 2009

Я разработал несколько переносных оберток вокруг розеток. Убедитесь, что вы не пошли по дурацкой линии невозврата, состоящей из событий WinSock2. Кроме этого, на мой взгляд, самые большие различия:

  • для запуска сети в Windows, вам нужно позвонить ::WSAStartup(), чтобы выключить его в Windows, запустить ::WSACleanup(); в линуксе ничего не делать,
  • close() в Linux - closesocket() в Windows,
  • размеры буфера по умолчанию различаются как для драйверов, так и для операционных систем, поэтому обязательно установите их, используя SO_RCVBUF и SO_SNDBUF,
  • SO_REUSEADDR крадет адрес в Windows, позволяет частое повторное открытие в Linux; вы, вероятно, захотите использовать этот флаг только в Linux,
  • для создания неблокирующего сокета используется ::ioctlsocket() в Windows, ::fcntl() в Linux,
  • заголовочные файлы разные, <sys/socket.h> и друзья в Linux, <WinSock.h> в Windows,
  • для переносимости, возможно, проще всего использовать ::select() для ожидания поступления данных,
  • fd_set s совершенно разные в Windows / Linux; это актуально, только если вам нужно оптимизировать инициализацию fd_set с, например, при добавлении / удалении произвольных сокетов,
  • в Windows любой поток, висящий на сокете, освобождается с кодом ошибки при закрытии сокета, в Linux поток остается в ожидании. Если поток блокирует сокет, например, ::recvfrom(), вы можете рассмотреть возможность использования ::sendto(), чтобы освободить поток остановки в Linux.

Все остальное, что мне когда-либо было нужно, просто получалось из Лоды.

3 голосов
/ 06 мая 2009

Winsocks не очень совместимы с розетками Posix:

  • В Winsocks сокет имеет тип SOCKET. В Posix это просто файловый дескриптор (int), с которым вы можете выполнять обычные вызовы read() и write().
  • Они не возвращают ошибки одинаково.
  • Они не поддерживают некоторые параметры на recv() и send().
  • Вы должны инициализировать и унифицировать библиотеку Winsocks с двумя специальными функциями.
  • Не думаю, что вы можете закрыть сокеты Windows с помощью shutdown() или close(). Вместо этого это что-то вроде closesocket().

Должно быть, больше различий, но это то, что я помню сейчас. Если вам нужна переносимость с Winsocks, у вас будет небольшая библиотека для закрытия сокета, печати сообщения об ошибке и т. Д.

Я бы, наверное, пошел с boost::asio лично (хотя я никогда не использовал его).

2 голосов
/ 16 июня 2009

Взгляните на библиотеку «Адаптивная среда связи» (ACE): (домашняя страница ACE) Он предоставляет несколько хороших абстракций и большую гибкость в виде переносимой библиотеки, которая поддерживает Windows, MacOS и Linux. У этого есть немного крутая кривая изучения, но я получил очень хорошее значение от этого.

1 голос
/ 24 июня 2009

Посмотрите на это ... http://sourceforge.net/projects/cpp-sockets/

1 голос
/ 06 мая 2009

Сколько сокетов вы будете использовать? Я сделал несколько приложений, где сокеты были довольно высокого уровня (открывать, читать, писать) и отлично работали от Windows до Linux. Если это больше, чем это - иди с наддува.

1 голос
/ 06 мая 2009

Честно говоря, я бы использовал boost :: asio в качестве первого предпочтения. Если вы действительно хотите разбираться с API сокетов, вы можете использовать стандартный API сокетов в стиле BSD как для Windows, так и для Linux - просто в Windows вам нужно будет связать (и инициализировать) Winsock2, тогда как В Linux у вас не будет отдельной библиотеки для ссылок.

...