KnigaRead.com/
KnigaRead.com » Компьютеры и Интернет » Программирование » А. Григорьев - О чём не пишут в книгах по Delphi

А. Григорьев - О чём не пишут в книгах по Delphi

На нашем сайте KnigaRead.com Вы можете абсолютно бесплатно читать книгу онлайн А. Григорьев, "О чём не пишут в книгах по Delphi" бесплатно, без регистрации.
Перейти на страницу:

□ самостоятельно разобраться с не упомянутыми здесь функциями getsockname, gethostbyaddr и getaddrbyhost.

Из приведенных примеров видно, что стандартные сокеты достаточно интегрируются с пользовательским интерфейсом, однако приложение, использующее их, вынуждено самостоятельно опрашивать сокеты с определённой периодичностью (например, по таймеру). Это не совпадает с принятой в Windows схемой событийного управления программой, основанной на принципе "пусть мне скажут, когда что-то произойдет, и я отреагирую". Именно поэтому стандартные сокеты были расширены и появились сокеты Windows, с которыми мы познакомимся далее.

2.2. Сокеты Windows

В предыдущих разделах мы рассмотрели те методы работы с сокетами, которые восходят еще к сокетам Беркли. Разработчики библиотеки сокетов для Windows добавили в нее также поддержку новых методов, упрощающих работу с сокетами для приложений, имеющих традиционную для Windows событийно-ориентированную модель. В Windows можно использовать асинхронные сокеты и перекрытый ввод-вывод. Далее мы рассмотрим эти расширения, а также ряд новых функций, пришедших на смену "морально устаревшим" функциям из стандартных сокетов.

Материал здесь, как и ранее, не претендует на полноту, а предназначен лишь для знакомства с наиболее часто употребляемыми возможностями библиотеки сокетов. По-прежнему рассматриваются только протоколы TCP и UDP. Не будут затронуты такие вопросы, как поддержка качества обслуживания, пространства имен, простые сокеты (RAW_SOCK) и SPI (Service Provider Interface); Тем, кто захочет самостоятельно разобраться с данными вопросами, рекомендуем книгу [3].

2.2.1. Версии Windows Sockets

При рассмотрении функции WSAStartup уже упоминалось, что существуют разные версии библиотеки сокетов, которые заметно различаются по функциональности. К сожалению, полный перечень существующих на сегодняшний день версий Windows Sockets и их особенностей в документации в явном виде не приводится, но, изучая разрозненную информацию, можно сделать некоторые выводы, которые приведены в табл. 2.1. В дальнейшем, если не оговорено иное, под WinSock 1 мы будем подразумевать версию 1.1, под WinSock 2 — версию 2.2.


Таблица 2.1. Версии Windows Sockets

Версия Комментарий 1.0 Упоминается только вскользь. Видимо, настолько старая версия, что ее поддержка в чистом виде в современных системах отсутствует 1.1 Основная подверсия первой версии библиотеки. По умолчанию входила во все версии Windows до Windows 95 включительно. Ориентирована на 16-разрядные системы с корпоративной многозадачностью 2.0 В чистом виде никуда не ставилась. Ориентирована на 32-разрядные системы с вытесняющей многозадачностью. Исключены некоторые устаревшие функции 2.2 Основная подверсия второй версии библиотеки. По умолчанию входит в состав Windows 98/NT 4/2000 а также видимо, и более поздних версий. Для Windows 95 существует возможность обновления Windows Sockets до этой версии

WinSock 1 в 16-разрядных версиях Windows реализуется библиотекой WinSock.dll, в 32-разрядных — WSock32.dll. WinSock 2 реализуется библиотекой WS2_32.dll, и. кроме того, часть функций вынесена в отдельную библиотеку MSWSock.dll. При этом для сохранения совместимости WS2_32.dll содержит даже те устаревшие функции, которые формально исключены из спецификации WinSock 2. В тех системах, в которых установлена библиотека WinSock 2, WSock32.dll не реализует самостоятельно практически ни одной функции, а просто импортирует их из WS2_32.dll и MSWSock.dll. WSock32.dll требуется только для обратной совместимости, в новых программах необходимости в этой библиотек нет.

Как это ни удивительно, но в Delphi даже 2007-й версии (не говоря уже о более ранних) отсутствует поддержка WinSock 2. Стандартный модуль WinSock импортирует функции только из WSock32.dll, поэтому программисту доступны только функции WinSock 1. Разумеется, импортировать функции WinSock 2 самостоятельно не составит труда. Более того, в Интернете можно найти уже готовые модули, импортирующие их (например, на сайте Алекса Коншина http://home.carthlink.net/~akonshin/delphi_ru.htm). Тем не менее, чтобы избежать разночтений, мы не будем использовать какой-либо готовый модуль для импорта и примем следующее соглашение: если прототип функции приведен только на Паскале, значит, эта функция есть в модуле WinSock. Если же прототип приведен и на C/C++ и на Паскале, значит, функция в WinSock не описана. В этом случае прототип функции на C/C++ берется из MSDN, а перевод на Паскаль — импровизация автора книги. В некоторых случаях возможны несколько вариантов перевода, поэтому не стоит рассматривать приведенный здесь перевод как истину в последней инстанции. Тем, кто будет самостоятельно импортировать функции из WS2_32.dll, следует помнить, что они имеют модель вызова stdcall (при описании прототипов функций мы для краткости будем опускать эту директиву).

Примечание

С 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, если в данный момент выполняется блокирующая операция и работа с сокетами невозможна.

Перейти на страницу:
Прокомментировать
Подтвердите что вы не робот:*