Интегрированные сети ISDN

         

Краткое описание сообщений об ошибках



Таблица 7.10. Краткое описание сообщений об ошибках



WinSock-код

Berkeley-эквивалент

Код ошибки

Значение

WSAEINTR EINTR 10004 Как в стандартном C
WSAEBADF EBADF 10009 Как в стандартном C
WSAEACCES EACCES 10013 Как в стандартном C
WSAEFAULT EFAULT 10014 Как в стандартном C
WSAEINVAL EINVAL 10022 Как в стандартном C
WSAEMFILE EMFILE 10024 Как в стандартном C
WSAEWOULDBLOCK EWOULDBLOCK 10035 Как в BSD
WSAEINPROGRESS EINPROGRESS 10036 Эта ошибка возникает, если какая-либо процедура WinSock вызвана во время исполнения блокирующей операции.
WSAEALREADY EALREADY 10037 Как в BSD
WSAENOTSOCK ENOTSOCK 10038 Как в BSD
WSAEDESTADDRREQ EDESTADDRREQ 10039 Как в BSD
WSAEMSGSIZE EMSGSIZE 10040 Как в BSD
WSAEPROTOTYPE EPROTOTYPE 10041 Как в BSD
WSAENOPROTOOPT ENOPROTOOPT 10042 Как в BSD
WSAEPROTONOSUPPORT EPROTONOSUPPORT 10043 Как в BSD
WSAESOCKTNOSUPPORT ESOCKTNOSUPPORT 10044 Как в BSD
WSAEOPNOTSUPP EOPNOTSUPP 10045 Как в BSD
WSAEPFNOSUPPORT EPFNOSUPPORT 10046 Как в BSD
WSAEAFNOSUPPORT EAFNOSUPPORT 10047 Как в BSD
WSAEADDRINUSE EADDRINUSE 10048 Как в BSD
WSAEADDRNOTAVAIL EADDRNOTAVAIL 10049 Как в BSD
WSAENETDOWN ENETDOWN 10050 Как в BSD. Ошибка возникает в любое время, когда приложение WinSock обнаруживает ошибку на нижележащем уровне.
WSAENETUNREACH ENETUNREACH 10051 Как в BSD
WSAENETRESET ENETRESET 10052 Как в BSD
WSAECONNABORTED ECONNABORTED 10053 Как в BSD
WSAECONNRESET ECONNRESET 10054 Как в BSD
WSAENOBUFS ENOBUFS 10055 Как в BSD
WSAEISCONN EISCONN 10056 Как в BSD
WSAENOTCONN ENOTCONN 10057 Как в BSD
WSAESHUTDOWN ESHUTDOWN 10058 Как в BSD
WSAETOOMANYREFS ETOOMANYREFS 10059 Как в BSD
WSAETIMEDOUT ETIMEDOUT 10060 Как в BSD
WSAECONNREFUSED ECONNREFUSED 10061 Как в BSD
WSAELOOP ELOOP 10062 Как в BSD
WSAENAMETOOLONG ENAMETOOLONG 10063 Как в BSD
WSAEHOSTDOWN EHOSTDOWN 10064 Как в BSD
WSAEHOSTUNREACH EHOSTUNREACH 10065 Как в BSD
WSASYSNOTREADY 10091 Выдается WSAStartup, указывает, что сетевая субсистема использоваться не может.
WSAVERNOTSUPPORTED   10092 Выдается WSAStartup, указывая на то, что WinSock DLL не может поддерживать это приложение.
WSANOTINITIALISED   10093 Выдается любой процедурой кроме WSAStartup, указывая на то, что успешное исполнение WSAStartup не было осуществлено.
WSAEDISCON   10094 Выдается recv, WSARecv, чтобы отметить начало разрыва связи удаленным партнером
WSA_OPERATION_ABORTED   TBD Совмещенные по времени процедуры прерваны из-за закрытия соединения, или выполнения команды SIO_FLUSH в WSAIoctl
WSAHOST_NOT_FOUND HOST_NOT_FOUND 11001 Как в BSD
WSATRY_AGAIN TRY_AGAIN 11002 Как в BSD
WSANO_RECOVERY NO_RECOVERY 11003 Как в BSD
WSANO_DATA NO_DATA 11004 Как в BSD
<
  • Современные версии WinSock обеспечивают протокольно- независимый доступ ко всем ресурсам сети, включая такие стандартные приложения, как DNS, SAP, X.500 и т.д.

  • Позволяют реализовать несколько сессий ввода/вывода одновременно.

  • Поддерживают любые стандартные уровни сервиса (QOS - Quality of service). Осуществляют объединение соединителей по группам в соответствии с их параметрами.

  • Допускается многопротокольная широковещательная или мультикастинг-адресация.

  • Предусматривается совместное использование соединителей несколькими процессами, условное создание соединителей и объединение их в группы.

  • Введено понятие WOSA-интерфейса (Windows Open Service Architecture), который обеспечивает связь между прикладной программой и сетевыми процедурами ОС. Этот интерфейс заметно упрощает программирование при работе с пакетами.
    Каждая процедура, распознаваемая WOSA, имеет в свою очередь несколько интерфейсов, ориентированных на конкретных сервис-провайдеров. Применение этих средств реализуется через DLL.
    WinSock, следуя модели WOSA, обеспечивает прикладной интерфейс для сетевого программирования (API - Application Programming Interface), который организует доступ к транспортным услугам и серверу имен сервис-провайдера (SPI - Service Provider Interfaces). SPI ориентирован на использование в рамках 32-битовой модели Microsoft Windows, включая Windows NT и Windows 95.
    Транспортные сервис-провайдеры (например, TCP/IP или IPX/SPX) и именные серверы (DNS) в WinSock представляют собой динамические библиотеки (DLL) с одной точкой входа для процедур инициализации WSPStartup или NSPStartup (обратите внимание на то, что здесь под сервис-провайдером подразумевается система, способная предоставить определенный вид услуг). Все остальные процедуры сервис-провайдера сделаны доступными для WinSock DLL через диспетчерскую таблицу. Динамическая библиотека сервис-провайдера загружаются в память WinSock DLL только по мере необходимости и выгружаются, когда они более не нужны. Динамическая библиотека сервис-провайдера имеет обычно расширение .WSP или .NSP.


    Процедуры WinSock SPI имеют префиксы:

    WSP WinSock Service Provider для транспортных услуг сервис-провайдера;
    WPU WinSock Provider Upcall для входа в WinSock DLL сервис-провайдера;
    WSC WinSock Configuration для входа в WinSock DLL инсталляционных приложений;
    NSP Name Space Provider для работы с сервером имен.

    Сервис- провайдеры WinSock при работе со строками используют UNICODE. WinSock DLL выполняют необходимые преобразования при работе с приложениями, использующими ANSI или UNICODE.
    Конкретный сервис-провайдер может поддерживать один или более протоколов. Так TCP/IP-провайдер должен как минимум поддерживать TCP- и UDP-протоколы, в то время как IPX/SPX-провайдер - IPX, SPX и SPX II. Каждый поддерживаемый протокол описывается в структуре WSAPROTOCOL_INFO, а набор таких структур представляет собой каталог используемых протоколов (более детальную информацию по данной тематике можно найти по адресу: www.stardust.com/winsock/ws_specs.htm).
    Одной из главных задач 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 и WSAAccept - WSPAccept, а socket и WSASocket - WSPSocket.
    Так как 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 интерпретируется как:

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

    Инсталляция стека протоколов возможна лишь после загрузки всех составных частей (слоевых и базовых протоколов).


    Структура WSAPROTOCOL_INFO для стека протоколов использует поле ProtocolChain для описания длины стека и идентификации каждой из составных частей. Отдельные протоколы, входящие в стек последовательно перечислены в массиве ProtocolChain.ChainEntries, нулевой элемент списка соответствует первому протоколу слоя.
    SDK (System Development Kit) для WinSock включает в себя инструментальную WinSock и отладочную DLL.
    При разработке протокольно-независимых приложений для систем клиент-сервер нужно зарегистрировать имя сервера в банке имен, только это может сделать его доступным извне. Программа-клиент может функционировать лишь при условии, если она способна найти необходимую ей процедуру в поле имен и получить доступ к соответствующему транспортному протоколу и адресной информации. Для тех кто работает с протоколами TCP/IP это может в начале вызвать определенные трудности, которые компенсируются возможностями создания программ, пригодных для широкого класса самых разнообразных протоколов (например, Novell). Под работой с полем имен здесь подразумевается возможность установления соответствия между протоколом и адресным атрибутом сетевой услуги, которой присвоено какое-то имя. Примерами таких полей имен могут служить уже используемые системы 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 может маршрутизовать прикладные операции в пространстве имен и переадресовывать их соответствующим серверам имен.
    Процедуры установки классов услуг, регистрации и обслуживания запросов осуществляются непосредственно через интерфейс API - SPI. Процедура 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, а применение псевдо-блокирующей техники не всегда давало удовлетворительный эффект. В ОС типа Windows 95 или Windows NT блокирующие процедуры уже не могут вызвать каких-либо проблем, более того, они уже представляются привлекательными. Интерфейс WinSock 2 API уже не поддерживает более псевдоблокировку, но для обеспечения совместимости с WinSock 1.1 он эмулирует этот механизм.
    В среде Win16, где настоящее блокирование не поддерживается ОС, блокирующие процедуры, которые не могут быть закончены немедленно, обслуживаются с использованием псевдоблокировки. Сервис-провайдер инициализирует процедуру, после чего входит в цикл, внутри которого осуществляет доставку любых сообщений Windows и проверяет завершение процедуры. Если процедура завершилась, или если вызван оператор WSPCancelBlockingCall, происходит выход из цикла, а блокирующая процедура завершается с соответствующим результатом.
    Эта схема вполне приемлема для простых приложений. Но она неприемлема для приложений, где должны реализоваться сложные схемы доставки сообщений, например, для модели MDI (Multiple Document Interface).


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

    Сервис-провайдер WinSock использует псевдоблокировку лишь при выполнении определенных условий:
  • Программа определена как блокирующая,

  • Соответствующий соединитель работает в блокирующем режиме,

  • Запрос не может быть выполнен немедленно.

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


    Объекты событий в WinSock представляют собой простые конструкции, которые могут создаваться и уничтожаться, они могут устанавливаться и сбрасываться. Клиент создает объект события и передает его дескриптор в качестве параметра таким процедурам как WSPSend и WSPEventSelect. Когда оговоренные условия выполнены, сервис-провайдер использует дескриптор для того, чтобы установить объект события с помощью оператора WPUSetEvent. При этом клиент WinSock SPI может находиться в состоянии блокировки-ожидания или в режиме запроса, ожидая, когда объект события будет установлен. Клиент может сбросить объект события в нуль, снова его установить и использовать снова.
    Субъект (приложение или сервис-провайдер), создавший объект события, ответственен и за его ликвидацию. Сервис-провайдер может это сделать с помощью WPUCloseEvent.
    Одной из главных задач сервис-провайдера является сообщение приложению о том, что произошло соответствующее сетевое событие. Список сетевых событий включает в себя:

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

    2. Возможность включения соединителя в одну из существующих групп.

    3. Учет провайдером значения 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 и представлена ниже.
    typedef enum

    {

    BestEffortService,

    ControlledLoadService,

    PredictiveService,

    GuaranteedService

    } GUARANTEE;

    typedef struct _flowspec

    {
    int32 TokenRate; /* В байтах/сек */
    int32 TokenBucketSize; /* В байтах */
    int32 PeakBandwidth; /* В байтах/сек */
    int32 Latency; /* В микросекундах */
    int32 DelayVariation; /* В микросекундах */

    GUARANTEE LevelOfGuarantee;
    int32 CostOfCall; /* Зарезервировано для будущего использования, должно быть = 0 */
    int32 NetworkAvailability /* только для чтения:

    1, если есть доступ,

    0, если нет */

    } FLOWSPEC, FAR * LPFLOWSPEC;

    typedef struct _QualityOfService

    {
    FLOWSPEC SendingFlowspec; /* Спецификация потока для данных */
        /* Посылка */
    FLOWSPEC ReceivingFlowspec; /* Спецификация потока для данных */
        /* Прием */
    WSABUF ProviderSpecific; /* Дополнительный провайдер */
        /* Специфические параметры */

    } QOS, FAR * LPQOS;

    Определения:


    LevelOfGuarantee Согласуемый уровень сервиса. Определены четыре уровня: гарантированный, предсказуемый, контролируемая загрузка и лучшее, что возможно. Предсказуемый уровень сервиса может дать наилучший результат при использовании определенного ресурса сети, в то время как гарантированный уровень соответствует необходимому уровню услуг конкретного приложения. Провайдеры могут предоставлять один, оба или ни одного их этих двух видов услуг.
    GuaranteedService Провайдер, поддерживающий гарантированный уровень сервиса, использует алгоритм очередей, в котором поток изолируется от влияния других потоков, и гарантирует, на сколько возможно, пропускную способность. Если отправитель шлет данные с большей скоростью, сеть может задержать или даже ликвидировать “лишнюю” часть потока. Если поток находится в пределах допустимого, то гарантируется и задержка отклика. Этот вид сервиса предусмотрен для приложений реального времени.
    PredictiveService Провайдер, поддерживающий предсказуемый уровень сервиса, гарантирует пропускную способность, по крайней мере равную TokenRate, на время соединения. Если отправитель шлет данные с большей скоростью, сеть может задержать или даже ликвидировать “лишнюю” часть потока. Значение задержки не гарантируется. Этот вид сервиса предназначен для приложений, способных адаптироваться к вариациям качества услуг, например, передача видео изображения.
    ControlledLoadService Этот уровень сервиса предполагает, что система сетевых устройств, которыми пользуется приложение, обеспечит условия работы, близкие к тем, которые достижимы при незагруженных каналах, для используемой транспортной среды. Приложения, использующие этот уровень сервиса, могут ожидать что:

    1. Большая часть передаваемых пакетов будет успешно доставлена (процент потерь определяется частотой ошибок транспортной среды).

    2. Задержка доставки не будет заметно превышать минимальное время распространения сигнала в используемой транспортной среде.
    BestEffortService Провайдеры, поддерживающие уровень сервиса “лучшее что возможно”, рассматривают спецификацию потока, как руководство к действию. И пытаются сделать все возможное, чтобы поддержать запрашиваемый уровень сервиса (без каких-либо твердых гарантий).
    TokenRate/TokenBucketSize Модель “блоков символов” (Token bucket model) используется для задания верхнего предела скорости обмена. Величина value -1 в этом случае означает, что не существует никаких ограничений на скорость обмена. Значение TokenRate (частота символов) выражается в байтах в сек, а TokenBucketSize в байтах. Блок имеет определенный объем (TokenBucketSize), который заполняется с определенной скоростью (TokenRate). Если в блоке достаточно места, приложение может посылать данные, что приводит к уменьшению свободного места. Если же свободного места нет, приложение должно прервать обмен и ждать. Если приложение в течение определенного времени слало данные со скоростью меньше чем TokenRate, оно может затем на некоторое время превысить эту скорость.
    PeakBandwidth Значение этого поля (выражается в байтах в сек) ограничивает максимальную скорость пересылки пакетов приложением. Промежуточные системы могут использовать эту величину для оптимизации использования имеющихся ресурсов.
    Latency Характеризует максимально приемлемую задержку между посылкой бита отправителем и его получением адресатом (в миллисекундах).
    DelayVariation Значение этого поля в миллисекундах характеризует разницу между максимальной и минимальной задержкой доставки пакетов. Этот параметр используется приложением для расчета объема входного буфера.
    CostOfCall Зарезервировано на будущее и должно равняться нулю.
    NetworkAvailability Это поле, доступное провайдерам только в режиме чтения, используется для сообщения приложению о доступности транспортной среды (например, знакомая многим ситуация потери спутника антенной).
    <


    Приложения, которые не склонны иметь дело с QOS-структурой непосредственно, могут воспользоваться именами известных видов сервиса и получить нужные данные с помощью запроса WSPGetQOSByName.
    Прежде чем использовать соединитель, надо связать его с локальным адресом. Это выполняется с помощью процедуры WSPBind, или WSPConnect.
    Сервер сначала создает соединитель, связывает его с известным локальным адресом (что позволяет клиенту найти его) и переводит соединитель в режим ожидания посредством WSPListen, готовя его к приему запросов на соединение. Одновременно система подготавливает структуру для формирования очереди запросов. Сервис-провайдер заносит поступающие запросы в очередь, где они ожидают обработки. Запросы могут быть удалены клиентом из очереди по таймауту.
    Если использован соединитель блокирующего типа, сервер может немедленно вызвать процедуру WSPAccept, которая вызовет блокировку на время ожидания запроса на соединение. В качестве альтернативы сервер может использовать один из механизмов обработки сетевых событий, описанный ранее. В зависимости от выбранного механизма провайдер или пошлет сообщение Windows или даст знать о приходе запроса на соединение через объект события.
    Клиент со своей стороны создаст соответствующий соединитель, запустит процедуру подключения и пошлет запрос WSPConnect, указав известный адрес сервера. Если соединитель является блокирующим, WSPConnect вызовет блокировку до тех пор пока сервер не получит и не обработает запрос на соединение или пока не произойдет таймаут. Клиент должен использовать механизм сетевых событий для отслеживания процесса соединения.
    Когда сервер запускает процедуру WSPAccept, сервис-провайдер инициализирует программу проверки условий, поставляемую приложением. В качестве параметров обращения используется информация, полученная вместе с запросом на соединение (берется из очереди запросов). Эта информация включат в себя адрес подключаемой ЭВМ, данные о пользователе и характеристику QOS, если таковая имеется.


    На основе полученной информации сервер определяет, принять данный запрос или нет.
    Если сервер принял запрос, он должен сформировать новый соединитель с теми же атрибутами что и соединитель ожидавший прихода запроса. Исходный соединитель остается в режиме ожидания последующих запросов.
    Для получения локального адреса сопряженными соединителями используется запрос WSPGetSockName. Это особенно полезно, когда послан запрос WSPConnect без предварительного вызова процедуры WSPBind.
    Как было сказано ранее, процедура WSPAccept позволяет воспользоваться поставляемой клиентом программой проверки условий, которая осуществляет условную обработку запросов на соединения, ожидающие обслуживания. Принятие решения осуществляется на основе информации, поступающей вместе с запросом (идентификатор источника запроса, QOS и т.д.). Если программа проверки условий возвращает флаг CF_ACCEPT, формируется новый соединитель с теми же свойствами, что и исходный. Если программа проверки вернет флаг CF_REJECT, запрос на соединение будет отвергнут. При возвращении флага CF_DEFER принятие решения откладывается, а запрос на соединение остается в очереди. Клиент должен будет осуществить вызов WSPAccept еще раз.
    Некоторые протоколы позволяют переслать информацию в процессе установления связи. Если такая информация получена, она помещается в буфер провайдера, а WinSock SPI получает указатель на этот буфер и длину записи. Если клиент WinSock SPI желает послать некоторую информацию в ответ, он может скопировать ее в буфер, предоставляемый сервис-провайдером.
    Разрыв соединения может быть выполнен несколькими способами. Для инициализации прерывания связи можно, например, применить процедуру WSPShutdown (с параметром how равным SD_SEND или SD_BOTH), и WSPSendDisconnect. Процедура WSPCloseSocket может быть применена и для аварийного прерывания соединения.
    Сервис провайдер сообщает о разрыве соединения по инициативе удаленного партнера с помощью сетевого события FD_CLOSE. При реализации процедуры разрыва соединения возможен обмен определенной информацией, если это предусмотрено используемым протоколом.


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

    Следует различать процедуры прерывания (shutdown) связи и ее разрыва (close). Прерывание связи сопряжено с определенным диалогом между партнерами, после чего связь “замораживается”, но дескриптор связи сохраняется. Существует два типа прерывания связи: аварийное (аппаратное) и нормальное. При нормальном прерывании любые данные, которые стояли в очереди, пересылаются до завершения процесса прерывания. При аварийном же прерывании непосланная информация теряется.
    В Windows Sockets, как процедура WSPShutdown, так и WSPSendDisconnect могут использоваться для инициализации прерывания связи. В то время как запрос WSPCloseSocket служит для ликвидации дескрипторов соединителей и освобождения связанных с ними ресурсов.
    Путем установки определенных значений для опций соединителей SO_LINGER и SO_DONTLINGER можно получит следующие варианты реализации процедуры WSPCloseSocket.
  • Процедура аварийного прерывания соединения, которая возвращается из WSPCloseSocket немедленно.

  • Нормальное прерывание соединения (graceful shutdown); задержка исполнения до завершения исполнения процедуры или до истечения заданного времени. Если таймаут наступает до завершения процедуры прерывания соединения, запускается процесс аварийного разрыва соединения.

  • Нормальное прерывание соединения с немедленным возвратом и завершением процедуры прерывания в фоновом режиме. Этот алгоритм реализуется по умолчанию. Приложение при этом не знает, когда и как завершается процесс прерывания соединения.

  • Для соединителей, соответствующих протоколам неориентированных на соединение, работа, выполняемая оператором WSPConnect, связана главным образом с установлением адреса места назначения по умолчанию, что позволит в дальнейшем использовать соединитель в операциях обмена, ориентированных на соединение (WSPSend and WSPRecv).


    Любые дейтограммы, полученные от отправителя с адресом, отличным от специфицированного, будут проигнорированы.
    Место назначения по умолчанию может быть изменено с помощью повторного вызова WSPConnect. Любая дейтограмма из входной очереди будет отброшена, если новый адрес отличается от адреса, заданного в предыдущем WSPConnect.
    Если новый адрес равен нулю, соединитель будет отсоединен, так как удаленный адрес не определен, в результате операторы WSPSend и WSPRecv возвратят флаг ошибки WSAENOTCONN, в то же время WSPSendTo и WSPRecvFrom могут использоваться по-прежнему. Существует три базовых способа выполнения операций ввода/вывода:
  • Блокирующий ввод/вывод,

  • Неблокирующий ввод/вывод с асинхронными сетевыми событиями,

  • Совмещенный ввод/вывод.

  • Первый вариант является режимом по умолчанию, неблокирующий вариант может использоваться на любом соединителе, который поставлен в соответствующий режим. Третья разновидность обмена реализуется только на соединителях, которые при формировании были объявлены совмещенными. Процедуры посылки WSPSend и WSPSendTo и приема WSPRecv и WSPRecvFrom реализуют все три указанных режима обмена. Сервис-провайдеры определяют метод обмена на основе режима работы соединителя, атрибутов и входных параметров.
    Простейшим режимом обмена в WinSock 2 является блокирующий ввод/вывод. Этот режим устанавливается по умолчанию. Любая операция ввода/вывода на блокирующем соединителе вернет управление системе только по завершении процедуры. Таким образом, в ходе любой сессии может выполняться только одна операция ввода/вывода. Это простой режим, но отнюдь не самый эффективный.
    Если соединитель находится в неблокирующем состоянии, любая операция обмена должна либо завершаться немедленно, либо возвращать флаг ошибки WSAEWOULDBLOCK, указывая, что операция не может быть завершена корректно. Необходим механизм для определения, когда следует попытаться выполнить операцию еще раз. Для решения этой проблемы определен список сетевых событий, наступление которых может контролироваться с помощью процедур WSPSelect, WSPAsyncSelect или WSPEventSelect.


    В WinSock 2 впервые разрешено совмещение нескольких процедур ввода/вывода и потребована поддержка этого режима всеми сервис-провайдерами. Этот режим возможен только для соединителей, сформированных с помощью WSPSocket с флагом WSA_FLAG_OVERLAPPED.
    Для приема данных клиент может воспользоваться процедурами WSPRecv или WSPRecvFrom, чтобы указать буферы, куда будут записываться данные. Если один или более буферов подготовлены приложением до начала обмена, информация будет заноситься непосредственно в буферы пользователя и многоступенчатое копирование будет исключено. Если буферов заранее приложением не подготовлено, информация заносится сервис-провайдером во внутренний буфер и система ждет запроса, чтобы перенести данные в буфер приложения. Исключением из этого правила является случай, когда приложение использует WSPSetSockOpt для установления нулевого размера входного буфера. В этом варианте данные принимаются лишь при наличии указателей на буфер приложения. При посылке информации клиенты для выдачи указателей на буфер данных используют WSPSend или WSPSendTo.
    В совмещенном режиме процедуры посылки и получения данных завершаются немедленно. Полученный по возврату нуль, указывает на то, что процедура завершилась успешно. То есть, сформирован соответствующий объект события или программа завершения установлена в очередь с помощью WPUQueueApc. Возврат флага SOCKET_ERROR, сопряженного с кодом ошибки WSA_IO_PENDING, указывает, что совмещенная операция успешно начата и будет позднее сообщено, когда выходной буфер будет свободен или входной буфер будет заполнен. Любые другие коды ошибок говорят о сбое.
    Совмещаться могут как операции ввода, так и вывода. Следует иметь в виду, что если было послано несколько блоков данных друг за другом, сообщения о завершении операций по их пересылке могут прийти в другом порядке. Тоже может произойти и при приеме данных.
    Сервис-провайдеры имеют два способа сообщать о завершении совмещенных по времени операций: установка объекта события, заданного программой-клиентом, или запуск заданной клиентом программы завершения.


    В обоих случаях каждой из совмещенных операций ставится в соответствие структура WSAOVERLAPPED. Память для размещения этой структуры выделяется клиентом и используется им для указания того, какой из объектов следует установить при завершении процесса обмена. Структура WSAOVERLAPPED может использоваться сервис-провайдером для хранения дескриптора соответствующей совмещенной процедуры. Для извлечения нужной информации из указанной структуры можно воспользоваться оператором WSPGetOverlappedResult.
    Если параметр lpCompletionRoutine совмещенной операции не равен нулю, то сервис-провайдер может вызвать программу завершения, специфицированную клиентом. WinSock DLL предлагает асинхронную процедуру вызова (APC) программ завершения обмена.
    Для реализации той или иной функции в рамках сессии сервис-провайдер вызывает сначала процедуру WPUQueueApc. Сервис-провайдер должен позаботиться о том, чтобы процесс, соответствующий выбранному контексту, был активным до вызова функции WPUQueueApc.

    WPUQueueApc берет в качестве входных параметров указатель на структуру WSATHREADID, указатель на процедуру APC и 32-разрядный контекстный код. Сервис-провайдеры всегда получают указатель на соответствующую структуру WSATHREADID через параметр lpThreadId. Провайдер должен запомнить структуру WSATHREADID и выдать указатель на ее копию в качестве параметра оператора WPUQueueApc.
    Так как механизм APC работает только с одним 32-разрядным контекстным кодом, процедура APC не может быть сама программой завершения, заданной клиентом. Сервис-провайдер должен выдать указатель на свою собственную процедуру APC, которая, используя контекстный код, обеспечивает доступ к необходимой информации для совмещенной операции обмена и вызывает заданную клиентом программу завершения.
    Сервис-провайдер должен позволить клиентам WinSock 2 вызов процедур чтения или записи во время выполнения процедуры завершения обмена и гарантировать, что для данного соединителя не будет допущено вложение операций завершения.
    Структура WSAOVERLAPPED создает коммуникационную среду между запуском совмещенной операции обмена и последующим ее завершением.


    Структура WSAOVERLAPPED совместима со структурой OVERLAPPED для Win32:
    typedef struct _WSAOVERLAPPED {
    DWORD Internal; // Зарезервировано
    DWORD InternalHigh; // Зарезервировано
    DWORD Offset; // Зарезервировано
    DWORD OffsetHigh; // Зарезервировано
    WSAEVENT hEvent;  

    } WSAOVERLAPPED, LPWSAOVERLAPPED;
    Internal и InternalHigh Резервное поле, которое используется объектом, вовлеченным в совмещенные операции ввода/вывода. Для IFS-провайдеров это поле используется базовой операционной системой (IFS - Installable File System - инсталлируемая файловая система).
    Offset и OffsetHigh Поле зарезервировано для сервис-провайдеров.
    hEvent Если совмещенные операции ввода/вывода запущены в отсутствии программ завершения (lpCompletionRoutine равно NULL), тогда это поле должно содержать дескриптор (указатель) объекта WSAEVENT. В противном случае (lpCompletionRoutine не равно NULL) клиент может использовать это поле как сочтет нужным.

    Приоритетные данные могут доставляться пользователю независимо от обычной информации. Для коммуникационных протоколов, где предусмотрена пометка данных как срочные (например, TCP, позволяющий доставку срочной информации в общем потоке данных) система извлекает приоритетную информацию из общего потока и запоминает отдельно.
    Пользователь может определить, имеется ли приоритетная непрочитанная информация, используя процедуру WSPIoctl(SIOCATMARK). Для протоколов, где положение приоритетной информации в общем потоке имеет смысл, сервис-провайдер обеспечивает указатели, определяющие это положение. Для таких протоколов допускается обработка приоритетных данных в общем информационном потоке. Это достигается путем установки опции соединителя SO_OOBINLINE (OOB - Out-Of-Band). Для других протоколов, где блоки приоритетных данных независимы от общего информационного потока, попытка установить опцию SO_OOBINLINE вызовет ошибку. Приложение может использовать команду SIOCATMARK WSPIoctl для определения наличия непрочитанных блоков приоритетной информации.


    При запрещении SO_OOBINLINE (disabled - значение по умолчанию):
    Сервис-провайдер WinSock сообщает клиенту о FD_OOB событиях, если клиент зарегистрирован для этого с помощью процедуры WSPAsyncSelect, точно таким же образом FD_READ используется для сообщения о присутствии обычных данных. Таким образом, FD_OOB посылается, когда поступает приоритетная информация, а также когда данные прочитаны с использованием флага MSG_OOB, в условиях присутствия приоритетных данных, подлежащих чтению. Сообщение FD_READ для приоритетных данных не посылается.
    Сервис-провайдер WinSock возвращает соответствующий набор exceptfds при выполнении процедуры WSPSelect, если приоритетные данные присутствуют в очереди соединителя.
    Клиент может вызвать WSPRecv с MSG_OOB для чтения блока приоритетных данных.
    Клиент может вызвать процедуру WSPRecv без MSG_OOB для чтения потока обычной информации. Блок приоритетных данных не может появиться в потоке обычных данных. Если приоритетные данные остаются после запроса WSPRecv, сервис-провайдер дает сообщение клиенту с помощью флага FD_OOB или через exceptfds при использовании запроса B>WSPSelect.
    Для протоколов, где приоритетные данные находятся в потоке обычных данных, одного запроса WSPRecv недостаточно. Один вызов WSPRecv вернет обычные данные до маркера, и потребуется второй запрос WSPRecv для чтения данных после маркера.
    При разрешении SO_OOBINLINE (enabled):
    Сообщение FD_OOB не посылается для приоритетных данных, а процедуры WSPSelect и WSPAsyncSelect рассматривают эти данные как обычные, о типе информации можно судить по readfds соединителя или по сообщению FD_READ, соответственно.
    Клиент не может осуществлять вызов WSPRecv с флагом MSG_OOB для чтения блока приоритетных данных - в противном случае будет получен код ошибки WSAEINVAL.
  • Клиент может вызвать WSPRecv без флага MSG_OOB. Любая приоритетная информация будет доставлена в потоке обычных данных. Приоритетные данные не будут никогда перемешаны с обычными данными, необходимо три запроса чтения для получения приоритетной информации.


    Первый запрос возвращает обычные данные, предшествующие приоритетным, второй - возвращает приоритетные данные, третий возвращает нормальные данные, следующие за приоритетными.

  • Программа WSPAsyncSelect прекрасно приспособлена для выявления приоритетных данных, когда SO_OOBINLINE находится в состоянии выключено.
    Использование соединителя несколькими процессами одновременно организовано следующим образом. Базовый процесс для получения специальной структуры WSAPROTOCOL_INFO вызывает WSPDuplicateSocket. Эта процедура для передачи структуры другому процессу использует межпроцессный механизм коммуникаций (IPC). Последний процесс использует структуру WSAPROTOCOL_INFO при обращении к WSPSocket. Дескриптор соединителя, полученный в результате этой операции, будет дополнительным дескриптором исходного соединителя, который с этого момента может использоваться двумя процессами.
    Такой механизм разработан для того, чтобы удовлетворить как требованиям однопроцессной версии Windows 3.1, так и многопроцессным вариантам Windows 95 и NT. Следует иметь в виду, что совместное использование соединителей несколькими процессами возможно и без использования WSPDuplicateSocket, так как дескриптор соединителя доступен для всех процессов.
    Когда формируется дескриптор нового соединителя IFS-провайдер должен вызвать WPUModifyIFSHandle, а не-IFS-провайдер должен вызвать WPUCreateSocketHandle (IFS - Installable File System).
    Так как реально дублируются дескрипторы, а не сами соединители, все параметры соединения оказываются абсолютно идентичными.
    Контроль состояния используемых совместно соединителей осуществляется посредством WSPAsyncSelect и WSPEventSelect. Вызов одного из указанных запросов с одним из дескрипторов соединителя в качестве параметра, аннулирует любую предшествующую регистрацию событий для указанного соединителя, вне зависимости от того, какой из дескрипторов использован для новой регистрации. Таким образом, нельзя для процесса A иметь FD_READ-события, а для процесса B получать FD_WRITE-события.


    Процесс может вызвать WSPCloseSocket для дублирующего соединителя и старый дескриптор будет ликвидирован, в то время как сам соединитель, ему соответствующий, останется открытым вплоть до выполнения процедуры WSPCloseSocket.
    Два или более дескрипторов могут соответствовать одному и тому же соединителю и использоваться независимо для операций ввода/вывода. Однако, интерфейс WinSock не осуществляет какого-либо контроля за доступом, задача координации совместного использования соединителя является объектом ответственности самих процессов.
    Для простоты в дальнейшем термин “многоточечный” будет означать широковещательный или мультикастинг.
    В настоящее время многоточечные приложения (напр., IP-мультикастинг, ST-II, T.120, ATM UNI, и т.д.) значительно различаются по способу подключения узла к многоточечной сессии. Для декларации различных многоточечных атрибутов протокола в WinSock 2 используется структура WSAPROTOCOL_INFO. Просматривая эти атрибуты, программист может узнать, какие соглашения должны быть реализованы.
    В плоскости управления существует два типа различных сессий: rooted и non-rooted (корневые и некорневые). В случае корневого управления существует участник, называемый c_root, который отличается от всех остальных членов многоточечной сессии, которые называются c_leaf (периферийные члены группы). Участник сессии c_root должен оставаться в списке участников на протяжении всей многоточечной сессии, так как без его участия сессия будет прервана. c_root обычно инициирует многоточечную сессию путем установления связей с участниками типа c_leaf. c_root может вводить членов в группу, но c_leaf может подключиться к c_root позднее.
    Для некорневой плоскости управления, все участники многоточечной сессии являются периферийными узлами и не существует какого-то выделенного узла. Каждый c_leaf должен подключиться к многоточечной сессии, которая либо существует всегда (как в случае IP-мультикастинг адреса), или создана за счет какого-то внешнего механизма. При другом подходе c_root по-прежнему существует, но принадлежит сети в целом (не является одним из участников сессии).


    Так как корневой узел существует, некорневая управляющая плоскость может рассматриваться как неявно корневая. Примерами такого рода неявно корневых схем являются система IP-мультикастинга многоточечные блоки управления (Multipoint Control Unit - MCU) в H.320-видеоконференциях и т.д.
    В плоскости данных существует два стиля передачи информации: rooted и non-rooted (корневой и некорневой). В корневой плоскости данных существует выделенный участник, называемый d_root. Обмен данными происходит исключительно между d_root и остальными участниками многоточечной сессии, которые называются d_leaf. Трафик может быть однонаправленным или двунаправленным. Данные, посланные d_root, будут доставлены всем d_leaf, в то время как данные, отправленные d_leafs попадут только в d_root. В случае корневой плоскости данных не существует потока данных между периферийными узлами группы (d_leaf).
    В некорневой плоскости данных, все участники эквивалентны и любая информация, посланная участником, будет доставлена всем членам группы (сессии). Аналогично каждый узел d_leaf может получать данные ото всех остальных узлов группы, а также от любых узлов, не участвующих в данной сессии.
    В структуре WSAPROTOCOL_INFO имеется три поля атрибутов для выделения различных схем, используемых в плоскостях управления и данных:
  • XP1_SUPPORT_MULTIPOINT = 1 указывает на то, что этот протокол поддерживает многоточечные коммуникации, а последующие два поля имеют смысл.

  • XP1_MULTIPOINT_CONTROL_PLANE определяет, является ли плоскость управления корневой ( = 1) или не корневой ( = 0).

  • XP1_MULTIPOINT_DATA_PLANE указывает, является ли плоскость данных корневой ( = 1) или некорневой ( = 0).

  • В определенные моменты соединители, включенные в многоточечную сессию, могут по своему поведению отличаться от соединителей типа точка-точка. Так соединитель вида d_leaf в корневой плоскости данных может только посылать информацию участнику d_root. Это вызывает необходимость для клиента быть способным заявить об этом на стадии формирования соединителя.


    Делается это с помощью четырех многоточечных атрибутных флагов, которым присваивается определенное значение через параметр dwFlags в WSPSocket:
    SA_FLAG_MULTIPOINT_C_ROOT служит для создания соединителя, работающего как c_root. Это разрешено, если в WSAPROTOCOL_INFO указано, что имеет место контекст корневой плоскости управления.
    WSA_FLAG_MULTIPOINT_C_LEAF предназначен для генерации соединителя, работающего как c_leaf. Это возможно, если XP1_SUPPORT_MULTIPOINT присутствует в соответствующей записи WSAPROTOCOL_INFO.
    WSA_FLAG_MULTIPOINT_D_ROOT предполагает формирование соединителя, работающего как d_root. Это позволено, если в WSAPROTOCOL_INFO указано, что имеет место контекст корневой плоскости данных.
    WSA_FLAG_MULTIPOINT_D_LEAF служит для создания соединителя, работающего как d_leaf. Это допускается, если XP1_SUPPORT_MULTIPOINT присутствует в соответствующей записи WSAPROTOCOL_INFO.
    Когда создается многоточечный соединитель, один из двух флагов плоскости управления и один из двух флагов плоскости данных должны быть заданы в параметре dwFlags WSPSocket. Таким образом, при создании многоточечного соединителя могут быть реализованы четыре возможности: c_root/d_root, c_root/d_leaf, c_leaf/d_root, или c_leaf /d_leaf.
    Когда d_leaf-соединители используются в некорневой плоскости данных, обычно желательно управлять системой так, чтобы отправляемый трафик попадал назад в тот же соединитель. Команда SIO_MULTIPOINT_LOOP для WSPIoctl используется для разрешения или запрещения зацикливания многоточечного трафика.
    При использовании мультикастинга обычно необходимо специфицировать способ реализации сессии. Среди параметров сессии важную роль играет число вовлеченных сетевых сегментов. Для регулирования этого числа используется команда SIO_MULTICAST_SCOPE WSPIoctl. Нулевое значение числа сетевых сегментов означает, что мультикастинг пакеты не покинут пределы ЭВМ и могут попадать только во внутренние соединители. Значение единица (число по умолчанию) указывает, что мультикастинг-пакеты не могут выйти за пределы маршрутизатора локальной сети.


    Большие величины позволят распространение сообщений, проходящих соответствующее число маршрутизаторов. Этот код идентичен параметру времени жизни (TTL) в IP-мультикастинге.
    Многоточечный соединитель часто характеризуется его ролью в плоскости данных и управления. Следует иметь в виду, что один и тот же соединитель может иметь совершенно разную роль в разных плоскостях.
    В схемах для корневой плоскости периферийные узлы добавляются в многоточечную группу одним из двух способов. В первом методе, корень использует WSPJoinLeaf для инициализации соединения с периферийным узлом и приглашает его быть участником сессии. Со стороны периферийного узла приложение должно создать c_leaf-соединитель и использовать WSPListen для установки его в режим ожидания (listen). Периферийный узел получит сообщение FD_ACCEPT, которое означает приглашение присоединиться к многоточечной сессии, и может объявить о своем желании подключиться путем вызова WSPAccept. Корневое приложения получит сообщение FD_CONNECT, когда операция подключения к группе завершена.
    Во втором методе роли меняются. Корневой клиент создает соединитель c_root и переходит в режим ожидания (listen). Периферийный узел, желающий присоединиться к сессии, создает соединитель c_leaf и запускает WSPJoinLeaf, чтобы инициализировать соединение и доступ. Корневой клиент получает FD_ACCEPT, когда приходит запрос доступа, и принимает периферийный узел в группу посредством запроса WSPAccept. Периферийный узел получает FD_CONNECT, когда он принят в группу. Для случая IP-мультикастинга это эквивалентно опции соединителя IP_ADD_MEMBERSHIP. Читателей, знакомых с использованием несвязного UDP-протокола в IP-мультикастинге, может смутить семантика, ориентированная на соединение, присутствующая здесь. В частности указание на то, что используется запрос WSPJoinLeaf для соединителя UDP и ожидание сообщения FD_CONNECT могут вызвать недоразумение. Существуют уже, однако, прецеденты использования такой семантики для протоколов, не ориентированных на соединение.


    Разрешено и иногда полезно, например, использовать процедуру WSPConnect для UDP-соединителей. Общим результатом применения семантики, ориентированной на соединение для несвязных соединителей, является ограничение на то, как эти соединители могут использоваться. UDP-соединитель, используемый в WSPJoinLeaf, будет иметь определенные ограничения, а ожидание сообщения FD_CONNECT (которое в этом случае указывает на посылку соответствующего IGMP-сообщения) является одним из таких ограничений. Существует три случая, когда клиент может использовать WSPJoinLeaf:
  • При работе в качестве многоточечного сервера (root), приглашая новый периферийный узел принять участие в сессии.

  • При работе в качестве периферийного узла, выполняя запрос подключения к корневой многоточечной сессии.

  • При работе в качестве периферийного узла, запрашивая подключение к некорневой многоточечной сессии (например, IP-мультикастинг).

  • Как было упомянуто ранее, WSPJoinLeaf используется для присоединения периферийного узла к многоточечной сессии. WSPJoinLeaf имеет те же параметры и семантику, что и WSPConnect за исключением того, что он возвращает дескриптор соединителя (как и WSPAccept), и имеет дополнительный параметр dwFlags. Параметр dwFlags показывает, будет ли соединитель работать только в режиме чтения, только в режиме записи или в обоих режимах. Только многоточечный соединитель может использоваться в качестве входного параметра s этой процедуры. Если многоточечный соединитель находится в неблокирующем состоянии, полученный дескриптор соединителя нельзя будет использовать до тех пор, пока не будет получено FD_CONNECT. Корневое приложение в многоточечной сессии может вызвать WSPJoinLeaf один или более раз для того, чтобы добавить новые узлы к текущей многоточечной сессии.
    Параметры дескриптора соединителя, присланного WSPJoinLeaf, варьируются в зависимости от того, является ли дескриптор c_root или c_leaf. Для c_root соединителя, параметр name означает имя определенного периферийного узла, который должен быть добавлен, а возвращенный дескриптор соединителя является c_leaf и соответствует вновь добавленному периферийному узлу.


    Некоторые многоточечные приложения могут позволять этому соединителю “постороннее” общение с корневым сервером.
    При вызове WSPJoinLeaf для соединителя c_leaf, параметр name содержит адрес корневого приложения (для схемы корневого управления) или существующей многоточечной сессии (некорневая схема управления), и возвращенный дескриптор соединителя является тождественным по отношению ко входному дескриптору соединителя. В корневой схеме управления, корневой клиент должен поставить свой c_root соединитель в режим ожидания с помощью WSPListen. При запросе периферийного узла о присоединении к группе присылается стандартное сообщение FD_ACCEPT. Корневой клиент использует для подключения нового периферийного узла обычную процедуру WSPAccept. Запрос WSPAccept присылает дескриптор соединителя c_leaf, точно также как и WSPJoinLeaf.
    Многоточечный корневой клиент является ответственным за прерывание сессии. Такое приложение может использовать WSPShutdown или WSPClosesocket для соединителя c_root, чтобы прислать всем членам группы соединителей c_leaf сообщение FD_CLOSE.
    Рассмотрим семантическое отличие многоточечных и обычных соединителей. В плоскости управления имеется существенное семантическое отличие между соединителями c_root и обычными соединителями точка-точка:
    1. Cоединитель c_root может использоваться в процедуре WSPJoinLeaf для подключения новых периферийных узлов;

    2. Постановка соединителя c_root socket в режим ожидания (путем вызова WSPListen) не препятствует тому, чтобы соединитель c_root использовался оператором WSPJoinLeaf для добавления в список участников нового периферийного узла или для посылки или получения информации;

    3. Закрытие соединителя c_root вызовет отправку всем сопряженным соединителям c_leaf сообщения FD_CLOSE.

    Не существует какого-либо семантического различия между соединителем c_leaf и традиционным соединителем в плоскости управления, за исключением того, что соединитель c_leaf может использоваться процедурой WSPJoinLeaf, а использование соединителя c_leaf в WSPListen указывает на то, что должны восприниматься только запросы многоточечного соединения.


    В плоскости данных семантическое отличие между соединителями d_root и традиционными соединителями заключается в следующем:
    1. Данные, посланные на соединитель d_root, будут доставлены всем членам группы узлов, участвующих в многоточечном обмене;

    2. Данные, полученные соединителем d_root, могут поступить от любого участника многоточечного обмена.

    Соединитель d_leaf в корневой плоскости данных не имеет каких-либо семантических отличий от традиционных соединителей, однако, в некорневой плоскости данных информация, посланная на соединитель d_leaf, поступит ко всем периферийным узлам группы. Данные могут передаваться любым участником многоточечной сессии. Информация о том, находится ли соединитель d_leaf в корневой или некорневой плоскости данных, хранится в структуре соединителя WSAPROTOCOL_INFO.
    Сводные данные по опциям Winsock 2 вместе с их значениями по умолчанию приведены в таблице 7.11 (см. также описания WSPGetSockOpt и WSPSetSockOpt). Сервис-провайдеры Windows должны распознавать все эти опции.

    Содержание раздела