Поделиться через


Общие сокеты

Функция WSADuplicateSocket реализована для обеспечения совместного использования сокетов между процессами. Исходный процесс вызывает WSADuplicateSocket , чтобы получить специальную структуру WSAPROTOCOL_INFO для идентификатора целевого процесса. Он использует механизм межпроцессного взаимодействия (IPC) для передачи содержимого этой структуры целевому процессу. Затем целевой процесс использует структуру WSAPROTOCOL_INFO в вызове WSPSocket. Дескриптор сокета, возвращаемый этой функцией, будет дополнительным дескриптором сокета для базового сокета, который, таким образом, становится общим. Сокеты можно совместно использовать между потоками в данном процессе без использования функции WSADuplicateSocket, так как дескриптор сокета действителен во всех потоках процесса.

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

Функция WSADuplicateSocket создает дескрипторы сокета, а не базовый сокет. В результате все состояния, связанные с сокетом, являются общими для всех дескрипторов. Например, операция setsockopt , выполненная с помощью одного дескриптора, впоследствии отображается с помощью метода getsockopt из любого или всех дескрипторов. Процесс может вызывать closesocket в дублированном сокете, и дескриптор будет освобожден. Однако базовый сокет остается открытым до тех пор, пока closesocket не будет вызван с последним оставшимся дескриптором.

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