Опубликован: 28.09.2007 | Уровень: специалист | Доступ: платный
Лекция 4:

Сокеты

Конкретный сервис-провайдер может поддерживать один или более протоколов. Так, TCP/IP-провайдер должен как минимум поддерживать TCP и UDP-протоколы. Каждый поддерживаемый протокол описывается в структуре WSAPROTOCOL_INFO, а набор таких структур представляет собой каталог используемых протоколов (более детальную информацию по данной тематике можно найти по адресу: http://www.ictp.trieste.it/~radionet/nuc1996/ref/winsock/wsspi22.doc).

Одной из главных задач WinSock DLL является выполнение функции регулировщика информационных потоков между приложениями и сервиспровайдерами. Каждый сервиспровайдер взаимодействует только с WinSock DLL. WinSock DLL заботится об объединении потоков событий от разных сервиспровайдеров и направлении их приложению. Эта библиотека берет на себя функции арбитража и синхронизации. Взаимоотношения между сервиспровайдерами (даже если они поддерживают разные протоколы) улаживаются также WinSock DLL.

Работа WinSock DLL базируется на параметрах сокетов, которые задаются при формировании ( socket и WSASocket ), именно эта информация определяет, какой из сервис-провайдеров будет задействован. Для выбора сервис-провайдера применяется процедура WSPSocket. В случае процедуры socket, WinSock DLL находит запись в структуре WSAPROTOCOL_INFO, которая соответствует входным параметрам (идентификатор стека протоколов, тип сокета, протокол).

Сервис­-провайдеры используют сетевые протоколы низкого уровня. WinSock DLL осуществляет управление на среднем уровне, обеспечивая связь транспортных протоколов с приложениями.

Транспортный SPI WinSock аналогичен WinSock API с точки зрения базовых процедур с сокетами. Так, процедурам connect и WSAConnect ставится в соответствие WSPConnect ; accept и WSAAcceptWSPAccept, а socket и WSASocketWSPSocket.

Так как WinSock DLL не поставляется теперь разработчиками стека протоколов, расширение функциональных возможностей представляет определенную проблему. Для преодоления этих трудностей новейшие версии WinSock используют процедуру WSAIoctl, чтобы помочь сервис-провайдерам на практике реализовать какие-­либо функциональные новшества.

Для введения расширенных возможностей приложение должно запросить указатель на точку входа в соответствующую программу. Это делается с помощью процедуры WSAIoctl, используя команду SIO_GET_EXTENSION_FUNCTION_ POINTER. При этом входной буфер процедуры WSAIoctl содержит идентификатор запрашиваемой функции, в выходной буфер будет занесен указатель на нужную программу.

Идентификаторы, присвоенные новым функциям, должны быть уникальными глобальными идентификаторами GUID (Global Unique Identifiers), которые присваиваются им поставщиками сервис-провайдеров.

Для того, чтобы транспортный протокол стал доступен через WinSock, он должен быть правильно инсталлирован и зарегистрирован в WinSock. Когда транспортный сервис-провайдер инсталлирован с помощью программы поставщика, соответствующая информация должна быть введена в конфигурационную базу данных, чтобы дать WinSock DLL необходимые данные для взаимодействия с сервис-провайдером.

В WinSock DLL содержится процедура WSCInstallProvider для инсталляции программ поставщиков и процедура выгрузки этих программ WSCDeinstallProvider.

Структура WSAPROTOCOL_INFO поставляется для каждого протокола и указывает на то, является ли этот протокол базовым, слоевым или стеком. Величина поля ProtocolChain.ChainLen интерпретируется таким образом (таблица 4.9.3.).

Таблица 4.9.3.
0 протокол слоя базовый протокол (или стек, если стек состоит из одного протокола)
>1 стек протоколов.

Инсталляция стека протоколов возможна лишь после загрузки всех составных частей (слоевых и базовых протоколов). Структура WSAPROTOCOL_INFO для стека протоколов использует поле ProtocolChain для описания длины стека и идентификации каждой из составных частей. Отдельные протоколы, входящие в стек, последовательно перечислены в массиве ProtocolChain.ChainEntries, нулевой элемент списка соответствует первому протоколу слоя.

SDK (System Development Kit) для WinSock включает в себя инструментальную WinSock и отладочную DLL.

При разработке протокольно-­независимых приложений для систем клиент-сервер нужно зарегистрировать имя сервера в банке имен: только это может сделать его доступным извне. Программа-клиент может функционировать лишь при условии, если она способна найти необходимую ей процедуру в поле имен и получить доступ к соответствующему транспортному протоколу и адресной информации. Для тех, кто работает с протоколами TCP/IP, это может в начале вызвать определенные трудности, которые компенсируются возможностями создания программ, пригодных для широкого класса самых разнообразных протоколов. Под работой с полем имен здесь подразумевается возможность установления соответствия между протоколом и адресным атрибутом сетевой услуги, которой присвоено какое-­то имя. Примерами таких полей имен могут служить уже используемые системы DNS (Domain Name System), NDS (Netware Directory Services), X.500 и др. Поля имен могут быть динамическими, статическими и постоянными.

Динамические поля имен служат для краткосрочной регистрации сетевой услуги. Часто они базируются на широковещательной системе определения доступности той или иной услуги. Примерами таких систем являются SAP в среде Netware и NBP в среде Appletalk.

Статические поля имен формируются при первоначальном создании сервера имен и в дальнейшем могут изменяться лишь администратором сети. Традиционная система DNS относится именно к этой разновидности. Программа может пользоваться таким банком имен, но не может произвести туда запись.

Постоянное поле имен сходно с динамическим — запись туда происходит в реальном масштабе времени, но после регистрации имя записывается в постоянную память и остается там до тех пор, пока не придет запрос на ликвидацию этой записи. Примерами такой системы могут служить X.500 и NDS.

Некоторые поля имен организованы иерархически. X.500 и NDS, например, позволяют неограниченное число уровней вложения. Программные интерфейсы, предназначенные для посылки запросов в именные базы данных, сильно варьируются в зависимости от разновидности используемого поля имен. Сервер имен представляет собой резидентную программу, которая обеспечивает интерфейс между WinSock SPI и некоторой существующей базой данных имен.

Используемые услуги в WinSock группируются в классы услуг, и в пределах класса имя услуги должно быть уникальным.

Примерами классов услуг могут служить FTP и SQL. Каждому классу присваивается имя и идентификатор (ID). Имя класса может не быть уникальным, но идентификатор обязан быть неповторимым. В качестве идентификаторов классов услуг в Winsock применяются GUID (Globally Unique Identifiers). Для генерации GUID имеется специальная программа (UUIDGEN.EXE), которой может воспользоваться разработчик новых классов услуг.

DNS в Internet не имеет развитой системы для записи информации о классах услуг. Для TCP/IP-класса услуг GUID присвоен раз и навсегда.

WinSock DLL может маршрутизовать прикладные операции в пространстве имен и переадресовывать их соответствующим серверам имен.

Процедуры установки классов услуг, регистрации и обслуживания запросов осуществляются непосредственно через интерфейс APISPI. Процедура WSAGetServiceClassNameByServiceClassId не имеет аналога среди операторов SPI, так как эта процедура WinSock DLL осуществляет обращение к NSPGetServiceClassInfo.

Переключение сервера имен из активного состояния в пассивное и обратно осуществляется с помощью процедуры WSCEnableNSProvider. В активном состоянии могут находиться несколько серверов имен одновременно. Инициализация сервис-провайдеров выполняется с помощью процедуры WSPStartup (см. аналогично WSAStartup ). Каждой процедуре WSPStartup должна соответствовать процедура WSPCleanup.

Процедура WSPSocket имеет параметр flags, который позволяет контролировать атрибуты сокета. Флаг WSA_FLAG_OVERLAPPED указывает на то, что данный сокет будет использоваться в режиме совмещения процессов ввода/вывода.

Существуют атрибуты, ответственные за использование сокета для работы в многоточечном и/или мультикастинг режимах. Только сокеты, созданные для работы в многоточечном режиме, пригодны для запуска многоточечных сессий с помощью WSPJoinLeaf.

Сокет, созданный для работы в блокирующем режиме, может быть преобразован в неблокирующий с помощью процедур WSPAsyncSelect, WSPEventSelect или WSPIoctl. Перевод сокета в блокирующий режим производится посредством процедур WSPIoctl, если WSPAsyncSelect неактивен, или WSPEventSelect — если активен.

Процедура WSPCloseSocket ликвидирует дескриптор сокета, и все процессы, использующие этот сокет, будут прерваны.

Понятие блокировки для среды Windows было фундаментальным. В WinSock 1.1, блокирующие процедуры WinSock были проблемой, так как они парализовали взаимодействие приложения и надстройки Windows, а применение псевдо-блокирующей техники не всегда давало удовлетворительный эффект (вспомните "голубой экран смерти" в Windows95!). В ОС типа Windows NT блокирующие процедуры уже не могут вызвать каких-­либо проблем, более того, они уже представляются привлекательными. Интерфейс WinSock 2 API не поддерживает более псевдо-блокировку, но для обеспечения совместимости с WinSock 1.1 он эмулирует этот механизм.

В среде Win16, где настоящее блокирование не поддерживается ОС, блокирующие процедуры, которые не могут быть закончены немедленно, обслуживаются с использованием псевдо-блокировки. Сервис­-провайдер инициализирует процедуру, после чего входит в цикл, внутри которого осуществляет доставку любых сообщений Windows и проверяет завершение процедуры. Если процедура завершилась или если вызван оператор WSPCancelBlockingCall, происходит выход из цикла, а блокирующая процедура завершается с соответствующим результатом.

Эта схема вполне приемлема для простых приложений. Но она неприемлема для приложений, где должны реализоваться сложные схемы доставки сообщений, например, для модели MDI (Multiple Document Interface). Для таких приложений псевдо-блокировка должна быть реализована в самом приложении. Сервис­-провайдер в этом случае должен вызывать именно этот цикл. Для этого он должен получить указатель на него, обратившись к WPUQueryBlockingCallback.

Сервис-­провайдер WinSock не может исходить из предположения, что псевдо-блокировка, используемая приложением, обеспечит обработку сообщений. Если приложение не приспособлено для решения таких задач, оно откликнется флагом FALSE. Если сервис-провайдер требует обработки сообщений для своих внутренних нужд, он может вызвать процедуру PeekMessage до передачи управления циклу псевдо-блокировки в приложении.

Сервис­-провайдер WinSock использует псевдо-блокировку лишь при выполнении определенных условий:

  1. программа определена как блокирующая;
  2. соответствующий сокет работает в блокирующем режиме;
  3. запрос не может быть выполнен немедленно.

Если условия не выполнены, уход в цикл псевдоблокировки осуществлен не будет.

Если во время цикла псевдо-блокировки получено сообщение Windows, существует опасность, что будет предпринята попытка вызова еще одной процедуры WinSock. Из­-за трудностей управления этим процессом WinSock 1.1 запрещает такие вызовы. Любая попытка осуществить вложенный вызов процедур WinSock вызовет ошибку WSAEINPROGRESS. В WinSock 1.1 это ограничение справедливо как для блокирующих, так и для неблокирующих процедур. Имеется два исключения из этого правила: процедура, которая позволяет приложению проверить, находится ли система в цикле псевдо-блокировки ( WSAIsBlocking ), и процедура ухода из этого цикла ( WSPCancelBlockingCall ).

Илья Сидоркин
Илья Сидоркин

Добрый день! Подскажите пожалуйста как и когда получить диплом, после сдичи и оплаты?????

Наталья Шульга
Наталья Шульга

Курс "информационная безопасность" .

Можно ли на него записаться на ПЕРЕПОДГОТОВКУ по данному курсу? Выдается ли диплом в бумажном варианте и высылается ли он по почте?

виктор виноградов
виктор виноградов
Россия, Курская область
Евгений Миловзоров
Евгений Миловзоров
Россия, Пенза, ПГУ, 2004