Функция обратного вызова LPWSPDUPLICATESOCKET (ws2spi.h)

Функция LPWSPDuplicateSocket возвращает структуру WSAPROTOCOL_INFO , которую можно использовать для создания нового дескриптора сокета для общего сокета.

Синтаксис

LPWSPDUPLICATESOCKET Lpwspduplicatesocket;

int Lpwspduplicatesocket(
  [in]  SOCKET s,
  [in]  DWORD dwProcessId,
  [out] LPWSAPROTOCOL_INFOW lpProtocolInfo,
  [out] LPINT lpErrno
)
{...}

Параметры

[in] s

Дескриптор локального сокета.

[in] dwProcessId

Идентификатор целевого процесса, для которого будет использоваться общий сокет.

[out] lpProtocolInfo

Указатель на буфер, выделенный клиентом, достаточно большой для WSAPROTOCOL_INFO структуры. Поставщик службы копирует содержимое структуры сведений о протоколе в этот буфер.

[out] lpErrno

Указатель на код ошибки.

Возвращаемое значение

Если ошибка не возникает, функция LPWSPDuplicateSocket возвращает ноль. В противном случае возвращается значение SOCKET_ERROR, а конкретный номер ошибки доступен в lpErrno.

Код ошибки Значение
WSAENETDOWN
Произошел сбой сетевой подсистемы.
WSAEINVAL
Указывает, что один из указанных параметров был недопустимым.
WSAEINPROGRESS
Выполняется блокировка вызова сокетов Windows или поставщик услуг по-прежнему обрабатывает функцию обратного вызова.
WSAEMFILE
Больше нет доступных дескрипторов сокетов.
WSAENOBUFS
Нет свободного места в буфере. Не удается создать сокет.
WSAENOTSOCK
Дескриптор не является сокетом.

Комментарии

Исходный процесс вызывает LPWSPDuplicateSocket для получения специальной структуры WSAPROTOCOL_INFO . Он использует некоторый механизм межпроцессного взаимодействия (IPC) для передачи содержимого этой структуры целевому процессу, который, в свою очередь, использует его в вызове LPWSPSocket для получения дескриптора для дублированного сокета. Обратите внимание, что целевая структура WSAPROTOCOL_INFO может использоваться только один раз.

Поставщик услуг несет ответственность за выполнение любых операций, необходимых в контексте исходного процесса, и создание структуры WSAPROTOCOL_INFO , которая будет распознана, когда впоследствии она появится в качестве параметра для LPWSPSocket в контексте целевых процессов. Затем поставщик должен вернуть дескриптор сокета, который ссылается на общий базовый сокет. Элемент dwProviderReservedструктуры WSAPROTOCOL_INFO доступен для использования поставщиком услуг и может использоваться для хранения любой полезной информации контекста, включая дублированный дескриптор.

При выделении нового дескриптора сокета поставщик устанавливаемой файловой системы (IFS) должен вызывать WPUModifyIFSHandle, а поставщик, отличный от IFS, должен вызывать WPUCreateSocketHandle. Поставщик IFS может использовать функцию DuplicateHandle . Чтобы обеспечить правильное выполнение дублирования сокетов, поставщик служб, отличный от IFS, должен использовать функцию LPWSPDuplicateSocket .

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

Процесс-источник IPC Значение
1) LPWSPSocket, LPWSPConnect
2) Запрашивает идентификатор целевого процесса.
==>
3) Получает запрос идентификатора процесса и ответ.
4) Получает идентификатор процесса.
<==
5) Вызывает **LPWSPDuplicateSocket** для получения специальной структуры WSAPROTOCOL_INFO .
6) Отправляет структуру WSAPROTOCOL_INFO целевому объекту.
==> 7) Получает WSAPROTOCOL_INFO структуру.
8) Вызывает LPWSPSocket для создания дескриптора общего сокета.
9) Использует общий сокет для обмена данными.
10) LPWSPCloseSocket
<==

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

Так как дублируются дескрипторы сокетов, а не базовые сокеты, все состояния, связанные с сокетом, являются общими для всех дескрипторов. Например, операция WSPSetSockOpt , выполненная с помощью одного дескриптора, впоследствии отображается с помощью LPWSPGetSockopt из любого или всех дескрипторов. Процесс может вызвать LPWSPCloseSocket в дублированном сокете, и дескриптор будет освобожден. Однако базовый сокет будет оставаться открытым до тех пор, пока последний оставшийся дескриптор не вызовет LPWSPClosesocket .

Уведомления для общих сокетов зависят от обычных ограничений LPWSPAsyncSelect и LPWSPEventSelect. При выполнении любого из этих вызовов с использованием любого из общих дескрипторов отменяется предыдущая регистрация событий для сокета независимо от того, какой дескриптор использовался для этой регистрации. Таким образом, например, общий сокет не может доставлять события FD_READ для обработки A и FD_WRITE события для обработки B. В ситуациях, когда требуется такая тесная координация, разработчикам предлагается использовать потоки вместо отдельных процессов.

Многоуровневый поставщик служб предоставляет реализацию этой функции, но он также является клиентом этой функции, если и при вызове LPWSPDuplicateSocket следующего уровня в цепочке протоколов. Некоторые особые замечания относятся к параметру lpProtocolInfo этой функции, так как он распространяется вниз по уровням цепочки протоколов.

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

Одним из важнейших преимуществ этой политики является то, что поставщики базовых служб не должны знать о цепочках протоколов. Эта же политика применяется при распространении структуры WSAPROTOCOL_INFO через многоуровневую последовательность других функций, таких как LPWSPAddressToString, WSPStartup, LPWSPSocket или LPWSPStringToAddress.

Требования

   
Минимальная версия клиента Windows 2000 Professional [только классические приложения]
Минимальная версия сервера Windows 2000 Server [только классические приложения]
Верхняя часть ws2spi.h

См. также раздел

WPUCreateSocketHandle

WPUModifyIFSHandle