Почему там кулоны WSA для сокета (), подключение (), отправьте () и так далее, но не для closesocket ()?

Я собираюсь попытаться объяснить, что я означаю использовать несколько примеров:

  • сокет ()-> WSASocket ()
  • подключение ()-> WSAConnect ()
  • отправьте ()-> WSASend ()
  • sendto ()-> WSASendTo ()
  • recv ()-> WSARecv ()
  • recvfrom ()-> WSARecvFrom ()
  • ...
  • closesocket ()-> WSA??? ()

Это - ничто, что имеет значение очень, но является все еще чем-то, что дает мне ужасную головную боль.

11
задан Warren Young 18 March 2011 в 15:04
поделиться

3 ответа

closesocket доступен только в Windows, хотя я не уверен, почему они не следовали соглашению WSA там. Если вас это действительно беспокоит, вы можете создать свою собственную оболочку, которая вызывает closesocket.

Как упоминалось в WSASocket , должен быть сделан вызов closesocket.

3
ответ дан 3 December 2019 в 01:29
поделиться

Для полноты картины следует заметить, что независимо от того, касалось ли это работы с сетью, файлами, временем/датами или любой другой части API ANSI C / POSIX, MICROSOFT потратила много энергии, чтобы убедиться, что ее собственные поколения API Windows несовместимы с API Unix (которые существовали намного раньше Windows).

Та же стратегия используется MICROSOFT в отношении HTML (IE), HTTP (IIS), OpenDocuments (MS-Word) и т.д., поэтому обычное оправдание, что это случайно (или вызвано только желанием "инноваций"), более чем сомнительно.

Посмотрите, насколько C# является (плохой) копией Java - и в то же время умудряется быть полностью несовместимым (имена функций очень близки, если не идентичны, но количество параметров - или их порядок - отличается).

Теперь вы знаете, почему вы задали этот вопрос в первую очередь.

-5
ответ дан 3 December 2019 в 01:29
поделиться

Чтобы понять это, вы должны понимать, что Winsock был создан в начале 1990-х, когда динозавр Windows 3.x бродил по Земле.

API-интерфейс сокетов Windows («Winsock») отражает большую часть API-интерфейса сокетов BSD: там, где оба предоставляют заданную функцию, оба делают одно и то же. Итак, socket () - это один и тот же вызов для обоих API. Местами есть незначительные различия, но не более чем различия в сетевом программировании для других систем, основанных на сокетах BSD, таких как Linux и OS X.

Помимо реализации этого общего базового API, Winsock API также предоставляет множество расширений. к сокетам BSD. Многие имеют имена, аналогичные исходным функциям, но с префиксом WSA и верблюжьим регистром для всего остального. Это чисто расширенные версии исходных функций, а не их замена. Вы выбираете, какой из них использовать, в зависимости от того, нужна ли вам расширенная функциональность и должна ли ваша программа быть переносимой в системы, которые предоставляют только API-интерфейс сокетов BSD. Например, WSASocket () принимает те же параметры, что и socket () , плюс три дополнительных, которые связаны с другими расширениями Winsock. Если вам не нужны расширения, вызов socket () не повлечет за собой реальных штрафов, а кроме того, вы получите преимущество переносимости.

В дополнение к этим простым расширениям существуют расширения Winsock, которые не имеют прямого эквивалента BSD, такие как WSAAsyncSelect () .Обычно это связано с различиями в способах написания программ Windows по сравнению с программами для систем Unixy. В этом конкретном случае WSAAsyncSelect () существует, чтобы упростить написание однопоточных программ с графическим интерфейсом пользователя, которые используют сокеты без сетевого ввода-вывода, блокирующего графический интерфейс, или наоборот . Это полезно сегодня, но абсолютно необходимо для успеха Winsock еще во времена Windows 3.1, в которой не было потоков или других полезных механизмов многопроцессорности и IPC.

Остается только несколько чудаков, таких как closesocket () и ioctlsocket () .

closesocket () совпадает с close (2) в POSIX / Unix, за исключением того, что принимает только сокеты, а не дескрипторы файлов. Это одна из причин смены названия, но настоящие причины берут начало в том историческом вопросе начала 1990-х, который я поднял выше. В те дни некоторые компиляторы Windows - их было больше , чем , чем сегодня, - включали эквиваленты POSIX API, чтобы упростить перенос кода с других платформ на Windows. Такие возможности были очень ограничены и не включали поддержку сокетов, но, тем не менее, имя функции close () в то время считалось «использованным» в Windows. Это уже неправда, но Winsock является продуктом своей истории и не может быть изменен сейчас.

История ioctlsocket () и ioctl () аналогична. Одно большое отличие состоит в том, что ioctlsocket () сильно ограничен в Windows по сравнению с тем, что ioctl () может делать в системе Unix.Он существует только для того, чтобы предоставить Windows несколько сетевых возможностей, которые первоначальные создатели Winsock считали полезными в API сокетов BSD. С годами многое из того, что вы можете делать с сокетами и ioctl () в системах Unixy, но не с ioctlsocket () , было добавлено в Windows через другие API, только один из которых это WSAIoctl () .

Я написал статью « История Winsock » для FAQ программиста Winsock (который я поддерживаю), в котором все это подробно описывается. Другая соответствующая статья - « Совместимость сокетов BSD ».

41
ответ дан 3 December 2019 в 01:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: