Почему есть WSA-подвески для socket (), connect (), send () и т. Д., Но не для closesocket ()? - PullRequest
11 голосов
/ 15 июля 2010

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

  • сокет () -> WSASocket ()
  • connect () -> WSAConnect ()
  • send () -> WSASend ()
  • sendto () -> WSASendTo ()
  • recv () -> WSARecv ()
  • recvfrom () -> WSARecvFrom ()
  • ...
  • closesocket () -> WSA ??? ()

Это не имеет большого значения, но все равно вызывает головную боль.

Ответы [ 4 ]

41 голосов
/ 16 июля 2010

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

API-интерфейс Windows Sockets («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 & mdash; было больше доступно тогда чем сегодня & mdash; включены эквиваленты 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

3 голосов
/ 15 июля 2010

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

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

1 голос
/ 23 августа 2015

Это написано в документации MSDN:

Переименованные функции

В двух случаях было необходимо переименовать функции, которые используются в сокетах Беркли, чтобы избежатьконфликтует с другими функциями Microsoft Windows API.

Close и Closesocket

Сокеты представлены стандартными файловыми дескрипторами в сокетах Беркли, поэтому функцию close можно использовать для закрытия сокетова также обычные файлы.Хотя ничто в Windows Sockets не мешает реализации использовать обычные файловые дескрипторы для идентификации сокетов, ничто и не требует этого.В Windows сокеты должны быть закрыты с помощью процедуры closesocket .В Windows использование функции close для закрытия сокета некорректно, и последствия этого не определены в данной спецификации.

Ioctl и Ioctlsocket / WSAIoctl

Различные CЯзыковые системы времени выполнения используют IOCTL для целей, не связанных с Windows Sockets.Как следствие, функции ioctlsocket и функция WSAIoctl были определены для обработки функций сокетов, которые выполнялись IOCTL и fcntl вБеркли Software Distribution.

0 голосов
/ 16 июля 2010

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

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

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

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

...