Примечание
С Delphi поставляется библиотека Indy (Internet Direct), в состав которой входит модуль IdWinSock2
, импортирующий почти все функции WinSock 2 из системных библиотек. Импорт в нем динамический, над каждой функцией сделана обертка, которая при первом вызове проверяет, была ли уже загружена функция из библиотеки, и при необходимости загружает ее. Чтобы реализовать это, имена всех функций изменены, а вызов идет через процедурные переменные, имена которых совпадают с оригинальными именами соответствующих функций.
WinSock 2 предлагает разработчику Service Provider Interface (SPI), с помощью которого можно добавлять в систему поддержку своих протоколов. Устаревшими объявлены функции, имеющие привязку к конкретным протоколам (например, уже знакомая нам функция inet_addr
, которая имеет смысл только при использовании протокола IP). Добавлены новые функции, которые призваны унифицировать операции с разными протоколами. Фактически если работать с WinSock 2, то программа может быть написана так, что сможет использовать даже те протоколы, которые не существовали на момент её разработки. Кроме того, добавлена возможность связи асинхронных сокетов с событиями вместо оконных сообщений, а также поддержка перекрытого ввода-вывода (в WinSock 1 он поддерживался только в линии NT и не в полном объеме). Добавлена поддержка качества обслуживания (Quality of Service, QoS — резервирование части пропускной способности сети для нужд конкретного соединения), поддержка портов завершения, многоадресной рассылки и регистрации имен. Большинство этих нововведений требуются для пользовательских программ относительно редко (или вообще не нужны), поэтому мы не будем заострять на них внимание. Далее будут рассмотрены асинхронные сокеты (связанные как с сообщениями, так и с событиями), перекрытый ввод-вывод, методы универсализации работы с протоколами и многоадресная рассылка.
2.2.2. Устаревшие функции WinSock 1
В этом разделе мы познакомимся с теми устаревшими функциями, которые не стоит применять в 32-разрядных программах. Рассмотрим мы их, разумеется, очень обзорно, только для того, чтобы после прочтения книги вас не смущали упоминания этих функций и связанных с ними ошибок, которые иногда встречаются в MSDN.
В 16-разрядных версиях Windows реализована так называемая корпоративная многозадачность: каждая программа время от времени должна добровольно возвращать управление операционной системе, чтобы та могла передать управление другой программе. Если какая-то программа при этом поведет себя некорректно и не вернет управление системе, то все остальные приложения не смогут продолжать работу. Другой недостаток такой модели — в ней невозможно распараллеливание работы в рамках одного процесса, т.е. создание нитей.
При такой модели многозадачности использование блокирующих сокетов может привести к остановке всей системы, если не будут приняты дополнительные меры. В Windows проблема решается следующим образом: библиотека сокетов во время ожидания периодически вызывает заранее указанную функцию. В 16-разрядных версиях Windows эта функция по умолчанию извлекает сообщение из системной очереди и передает его соответствующему приложению. Таким образом, остальные приложения не прекращают работу во время блокирующего вызова.
В очереди могут находиться сообщения и для того приложения, которое выполняет блокирующий вызов. В этом случае будет снова вызвана оконная процедура, инициировавшая блокирующую операцию. Это напоминает рекурсию, при которой процедура вызывает сама себя: в памяти компьютера будут одновременно две активации этой процедуры. Упрощенно это выглядит так: оконная процедура вызывает блокирующую функцию (например, accept), а та, в свою очередь, снова вызывает ту же самую оконную процедуру. При этом вторая активация не может выполнять никаких операций с сокетами: они будут завершены с ошибкой WSAEINPROGRESS
. Эта ошибка не фатальная, она указывает, что в данный момент выполняется блокирующая операция, и программа должна подождать ее завершения и лишь потом пытаться работать с сокетами (т.е. не раньше, чем первая активация оконной процедуры вновь получит управление). Существует специальная функция WSAIsBlocking
, которая возвращает True
, если в данный момент выполняется блокирующая операция и работа с сокетами невозможна.
Вторая активация процедуры может прервать блокирующий вызов с помощью функции WSACancelBlockingСаll
. При этом первая активация получит ошибку WSAECANCELLED
.
Читать дальше
Конец ознакомительного отрывка
Купить книгу