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

Сокеты

Использование сокета несколькими процессами одновременно организовано следующим образом. Базовый процесс для получения специальной структуры WSAPROTOCOL_INFO вызывает WSPDuplicateSocket. Эта процедура для передачи структуры другому процессу применяет межпроцессный механизм коммуникаций (IPC). Последний процесс использует структуру WSAPROTOCOL_INFO при обращении к WSPSocket. Дескриптор сокета, полученный в результате этой операции, будет дополнительным дескриптором исходного сокета, который с этого момента может использоваться двумя процессами.

Такой механизм разработан для того, чтобы удовлетворить как требованиям однопроцессной версии, так и многопроцессным вариантам Windows NT и XP. Следует иметь в виду, что совместное использование сокетов несколькими процессами возможно и без использования WSPDuplicateSocket, так как дескриптор сокета доступен для всех процессов.

Когда формируется дескриптор нового сокета IFS-провайдер должен вызвать WPUModifyIFSHandle, а неIFS-провайдер должен вызвать WPUCreateSocketHandle (IFS Installable File System).

Так как реально дублируются дескрипторы, а не сами сокеты, все параметры соединения оказываются абсолютно идентичными.

Контроль состояния используемых совместно сокетов осуществляется посредством WSPAsyncSelect и WSPEventSelect. Вызов одного из указанных запросов с одним из дескрипторов сокета в качестве параметра аннулирует любую предшествующую регистрацию событий для указанного сокета, вне зависимости от того, какой из дескрипторов применен для новой регистрации. Таким образом, нельзя для процесса A иметь FD_READ -события, а для процесса B получать FD_WRITE -события.

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

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

Для простоты в дальнейшем термин "многоточечный" будет означать широковещательный или мульти-кастинговый.

В настоящее время многоточечные приложения (напр., IP-мультикастинг, STII, T.120, ATM UNI, и т.д.) значительно различаются по способу подключения узла к многоточечной сессии. Для декларации различных многоточечных атрибутов протокола в WinSock 2 используется структура WSAPROTOCOL_INFO. Просматривая эти атрибуты, программист может узнать, какие соглашения должны быть реализованы.

В плоскости управления существует два типа различных сессий: rooted и nonrooted (корневые и некорневые). В случае корневого управления существует участник, называемый c_root, отличающийся от всех остальных членов многоточечной сессии, которые называются c_leaf (периферийные члены группы). Участник сессии c_root должен оставаться в списке участников на протяжении всей многоточечной сессии, так как без его участия сессия будет прервана. c_root обычно инициирует многоточечную сессию путем установления связей с участниками типа c_leaf. c_root может вводить членов в группу, но c_leaf может подключиться к c_root позднее.

Для некорневой плоскости управления все участники многоточечной сессии являются периферийными узлами, и не существует какогото выделенного узла. Каждый c_leaf должен подключиться к многоточечной сессии, которая либо существует всегда (как в случае IP-мультикастинг адреса), либо создана за счет какого-то внешнего механизма. При другом подходе c_root по-прежнему существует, но принадлежит сети в целом (не является одним из участников сессии). Так как корневой узел существует, некорневая управляющая плоскость может рассматриваться как неявно корневая. Примерами такого рода неявно корневых схем являются система IP-мультикастинга — многоточечные блоки управления (Multipoint Control UnitMCU) в H.320-видеоконференциях и т.д.

В плоскости данных также существует два стиля передачи информации: rooted и nonrooted (корневой и некорневой). В корневой плоскости данных имеется выделенный участник, называемый d_root. Обмен данными происходит исключительно между d_root и остальными участниками многоточечной сессии, которые называются d_leaf. Трафик может быть однонаправленным или двунаправленным. Данные, посланные d_root, будут доставлены всем d_leaf, в то время как данные, отправленные d_leafs, попадут только в d_root. В случае корневой плоскости данных не существует потока данных между периферийными узлами группы ( d_leaf ).

В некорневой плоскости данных все участники эквивалентны и любая информация, посланная участником, будет доставлена всем членам группы (сессии). Аналогично, каждый узел d_leaf может получать данные ото всех остальных узлов группы, а также от любых узлов, не участвующих в данной сессии.

В структуре WSAPROTOCOL_INFO имеется три поля атрибутов для выделения различных схем, используемых в плоскостях управления и данных.

  1. XP1_SUPPORT_MULTIPOINT = 1 указывает на то, что этот протокол поддерживает многоточечные коммуникации, а последующие два поля имеют смысл.
  2. XP1_MULTIPOINT_CONTROL_PLANE определяет, является ли плоскость управления корневой ( = 1 ) или не корневой ( = 0 ).
  3. 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.

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

  1. При работе в качестве многоточечного сервера (root) приглашает новый периферийный узел принять участие в сессии.
  2. При работе в качестве периферийного узла выполняется запрос подключения к корневой многоточечной сессии.
  3. При работе в качестве периферийного узла запрашивается подключение к некорневой многоточечной сессии (например, при 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_root может использоваться в процедуре WSPJoinLeaf для подключения новых периферийных узлов.
  2. Постановка сокета c_root в режим ожидания (путем вызова 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_lea f, поступит ко всем периферийным узлам группы. Данные могут передаваться любым участником многоточечной сессии. Информация о том, находится ли сокет d_leaf в корневой или некорневой плоскости данных, хранится в структуре сокета WSAPROTOCOL_INFO.

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

Каролина Попович
Каролина Попович
Евгений Виноградов
Евгений Виноградов

Прошел экстерном экзамен по курсу перепордготовки "Информационная безопасность". Хочу получить диплом, но не вижу где оплатить? Ну и соответственно , как с получением бумажного документа?

Сергей Смоляр
Сергей Смоляр
Россия, Ялта