Я собираюсь попытаться объяснить, что я означаю использовать несколько примеров:
Это - ничто, что имеет значение очень, но является все еще чем-то, что дает мне ужасную головную боль.
closesocket доступен только в Windows, хотя я не уверен, почему они не следовали соглашению WSA там. Если вас это действительно беспокоит, вы можете создать свою собственную оболочку, которая вызывает closesocket.
Как упоминалось в WSASocket , должен быть сделан вызов closesocket.
Для полноты картины следует заметить, что независимо от того, касалось ли это работы с сетью, файлами, временем/датами или любой другой части API ANSI C / POSIX, MICROSOFT потратила много энергии, чтобы убедиться, что ее собственные поколения API Windows несовместимы с API Unix (которые существовали намного раньше Windows).
Та же стратегия используется MICROSOFT в отношении HTML (IE), HTTP (IIS), OpenDocuments (MS-Word) и т.д., поэтому обычное оправдание, что это случайно (или вызвано только желанием "инноваций"), более чем сомнительно.
Посмотрите, насколько C# является (плохой) копией Java - и в то же время умудряется быть полностью несовместимым (имена функций очень близки, если не идентичны, но количество параметров - или их порядок - отличается).
Теперь вы знаете, почему вы задали этот вопрос в первую очередь.
Чтобы понять это, вы должны понимать, что 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 ».