Сокеты
WinSock 2 DLL имеет средства для формирования объектов событий, как для приложения, так и для сервис-провайдера, хотя на практике объекты событий создаются в основном приложениями. Для формирования объектов событий в WinSock имеется оператор WPUCreateEvent. Дескриптор объекта события имеет смысл лишь в контексте программы, его сформировавшей. В среде Win32 работа с объектами событий выполняется самой операционной системой.
Объекты событий в WinSock представляют собой простые конструкции, которые могут создаваться и уничтожаться, они могут устанавливаться и сбрасываться. Клиент создает объект события и передает его дескриптор в качестве параметра таким процедурам как WSPSend и WSPEventSelect. Когда оговоренные условия выполнены, сервиспровайдер использует дескриптор для того, чтобы установить объект события с помощью оператора WPUSetEvent. При этом клиент WinSock SPI может находиться в состоянии блокировки или в режиме запроса, ожидая, когда объект события будет установлен. Клиент может сбросить объект события в нуль, снова его установить и снова использовать.
Субъект (приложение или сервиспровайдер), создавший объект события, ответственен и за его ликвидацию. Сервиспровайдер может это сделать с помощью WPUCloseEvent.
Одной из главных задач сервиспровайдера является сообщение приложению о том, что произошло соответствующее сетевое событие. Список сетевых событий выглядит таким образом (таблица 4.9.4.).
FD_CONNECT | Канал до удаленной ЭВМ или для мультикастинг-сессии сформирован |
FD_ACCEPT | Удаленная ЭВМ выставила запрос на соединение |
FD_READ | Получены данные и их можно считать |
FD_WRITE | В буферах сервис-провайдера появилось свободное место и можно послать очередную порцию информации |
FD_OOB | Для чтения доступна высокоприоритетная информация |
FD_CLOSE | Удаленная ЭВМ закрывает канал |
FD_QOS | Произошло изменение оговоренного значения QOS (качества услуг) |
FD_GROOUP_QOS | Произошло изменение оговоренного значения QOS для данной группы сокетов |
Стандартный BSD-интерфейс сокетов имеет только одно средство получить информацию о сетевых событиях — оператор select. Этот метод не может дать информацию о событиях FD_QOS и FD_GROUP_QOS.
В Windows Sockets 1.1 используется асинхронный механизм получения информации о сетевых событиях. Для регистрации интересующих событий можно использовать процедуру WSPAsyncSelect. Когда нужное сетевое событие произойдет, соответствующему окну будет послано сообщение, заданное клиентом. Сервис-провайдер использует для тех же целей процедуру WPUPostMessage. В среде Win32 этот метод получения данных о событиях нельзя считать эффективным.
WSPEventSelect ведет себя практически так же, как WSPAsyncSelect, за исключением того, что вместо посылки сообщения Windows при сетевом событии типа FD_XXX устанавливается соответствующий объект события.
Факт прихода сетевого события FD_XXX сервис-провайдером запоминается. Вызов процедуры WSPEnumNetworkEvents вызывает копирование текущего содержимого памяти сетевых событий в буфер клиента, а основная память событий очищается.
Сервис-провайдеры (ISDN или ATM) могут использовать групповые значения QOS при формировании виртуального канала и повышения эффективности своей работы. Пакеты для сокетов в пределах группы мультиплексируются обычным образом.
Операторы WSPSocket и WSPAccept предназначены для формирования и подключения новых сокетов к той или иной группе. Однажды включенный в группу сокет остается в ней до своего закрытия. Группа прекращает свое существование, лишь когда последний сокет группы будет закрыт. Идентификатор группы сокетов может быть получен с помощью оператора WSPGetSockOpt с опцией SO_GROUP_ID. Узнать об относительном приоритете сокета в группе можно, воспользовавшись процедурой WSPGet/SetSockOpt с опцией SO_GROUP_PRIORITY.
Групповое значение QOS можно задать при выполнении WSPConnect, или WSPIoctl с SIO_SET_GROUP_QOS, если специфицированный сокет является учредителем группы. Оператор WSPIoctl с SIO_GET_GROUP_QOS может использоваться для получения группового значения QOS заданного сокета.
Для провайдеров, поддерживающих группирование сокетов, минимально необходимы следующие функции:
- создание новых групп и присвоение им уникальных идентификаторов;
- возможность включения сокета в одну из существующих групп;
- учет провайдером значения QOS порождающего сокета при формировании списка параметров нового сокета, включаемого в группу.
Существуют группы двух видов. Одни включают в себя сокеты, ориентированные на соединение, они могут быть подключены только к определенному адресу ЭВМ, остальные группы относятся к другому виду. Провайдер не может включить в группу сокет, который не удовлетворяет этому условию. Провайдер не может также выполнить соединение, если адресат не соответствует адресу места назначения группы сокетов. Групповой адрес места назначения определяется, когда выполняется процедура connect для первого из сокетов группы.
Единственный индивидуальный параметр сокета в группе — его внутренний уровень приоритета.
Провайдер должен уметь считывать значение приоритета, но он может полностью игнорировать этот параметр.
В настоящее время не существует каких-либо механизмов для сопоставления приоритетов сокетов, принадлежащих к разным группам, или сокетов вне групп.
Поддержка провайдеров групп не означает непременную поддержку различного качества услуг (QOS, см. RFC-1363).
Поддержание работы с приоритетами сокетов в пределах группы является рекомендательным требованием. Схема приоритетов WinSock 2 имеет смысл лишь для мультиплексирования данных при соединении точка-точка, например, в случае телефонной связи или любых других вариантов, реализующих коммутацию каналов.
Характер информационного обмена описывается спецификацией потока (flow specs), для каждого сокета используется две такие спецификации, по одной для каждого из направлений обмена. Запрос на соединение реализуется через процедуры WSPConnect или WSPIoctl с кодом команды SIO_SET_QOS/SIO_SET_GROUP_QOS. Спецификация потока параметрически задает уровень сервиса (QOS) и определяет механизм адаптации приложения к сетевым условиям. В WinSock 2 спецификация потока содержит следующие характеристики QOS.
- Описание источника информационного потока, которое характеризует способ, используемый приложением для введения потока данных в сеть. Эта спецификация выполняется в терминах модели маркерного ведра (token bucket) и включает частоту генерации маркеров, их размер, а также максимальное значение информационного потока.
- Задержка (latency) — приемлемые верхние пределы задержки и ее вариации.
- Гарантированный уровень обслуживания. Предполагается, что провайдер, который не способен обеспечить требуемый уровень сервиса (QOS), не сможет быть подключен.
- Цена (параметр зарезервирован на будущее).
- Параметры, специфические для провайдера (спецификация потока может быть расширена, чтобы имелась возможность описать некоторые особенности провайдера).
Для протоколов, ориентированных на соединение, более удобно для приложения оговаривать QOS при формировании соединения. Это делается путем запроса WSPConnect, направленного сервис-провайдеру. Если QOS было задано с помощью WSPIoctl, его значение может быть переписано при выполнении процедуры WSPConnect.
Бессвязные сокеты могут также использовать WSPConnect с целью установления определенного уровня QOS для канала связи с партнером
После каждой попытки установить связь провайдер производит коррекцию спецификации потока для того, чтобы наилучшим образом отразить реальную ситуацию в сети. Предполагается, что клиенты могут использовать текущую сетевую информацию, чтобы оптимально реализовать возможности сети.
Но после того как информация о состоянии сети получена, условия могут измениться, партнеры могут согласовать другой уровень QOS, так что приложение должно быть готово ко всему. Для информирования клиента о возможных изменениях условий в Winsock используется механизм сетевых событий ( FD_QOS и FD_GROUP_QOS ). Сервис-провайдер должен генерировать события типа FD_QOS/FD_GROUP_QOS, если уровень сервиса изменился значительно. Клиент должен использовать WSPIoctl с кодами команд SIO_GET_QOS и/или SIO_GET_GROUP_QOS, чтобы получить соответствующую спецификацию потока и выяснить, изменился ли уровень сервиса (QOS). Структура QOS должна актуализоваться вне зависимости от типа события FD_QOS/FD_GROUP_QOS. Если новый уровень сервиса неприемлем, клиент может попытаться приспособиться к новым условиям или закрыть соединение. При повторной попытке согласовать уровень QOS успешный выход из процедуры WSPIoctl указывает, что новое значение QOS приемлемо. Структура QOS в WinSock 2 описана в файле Winsock2.h.
Приложения, которые не склонны иметь дело с QOS-структурой непосредственно, могут воспользоваться именами известных видов сервиса и получить нужные данные с помощью запроса WSPGetQOSByName.
Прежде чем использовать сокет, надо связать его с локальным адресом. Это выполняется с помощью процедуры WSPBind, или WSPConnect.
Сервер сначала создает сокет, связывает его с известным локальным адресом (что позволяет клиенту найти его) и переводит сокет в режим ожидания посредством WSPListen, готовя его к приему запросов на соединение. Одновременно система подготавливает структуру для формирования очереди запросов. Сервис-провайдер заносит поступающие запросы в очередь, где они ожидают обработки. Запросы могут быть удалены клиентом из очереди по таймауту.
Если использован сокет блокирующего типа, сервер может немедленно запустить процедуру WSPAccept, которая вызовет блокировку на время ожидания запроса на соединение. В качестве альтернативы сервер может использовать один из механизмов обработки сетевых событий, описанный ранее. В зависимости от выбранного механизма, провайдер или пошлет сообщение Windows, или даст знать о приходе запроса на соединение через объект события.
Клиент со своей стороны создаст соответствующий сокет, запустит процедуру подключения и пошлет запрос WSPConnect, указав известный адрес сервера. Если сокет является блокирующим, WSPConnect вызовет блокировку до тех пор, пока сервер не получит и не обработает запрос на соединение или пока не произойдет таймаут. Клиент должен использовать механизм сетевых событий для отслеживания процесса соединения.
Когда сервер запускает процедуру WSPAccept, сервис-провайдер инициализирует программу проверки условий, поставляемую приложением. В качестве параметров обращения используется информация, полученная вместе с запросом на соединение (берется из очереди запросов). Эта информация включат в себя адрес подключаемой ЭВМ, данные о пользователе и характеристику QOS, если таковая имеется. На основе полученной информации сервер определяет, принять данный запрос или нет.
Если сервер принял запрос, он должен сформировать новый сокет с теми же атрибутами, что и сокет, ожидавший прихода запроса. Исходный сокет остается в режиме ожидания последующих запросов.
Для получения локального адреса сопряженными сокетами используется запрос WSPGetSockName. Это особенно полезно, когда послан запрос WSPConnect без предварительного вызова процедуры WSPBind.