dwProviderReserved: DWORD;
szProtocol: array [0..WSAPROTOCOL_LEN] of Char;
end;
Расшифровка полей типа TWSAProtocolInfo
есть в MSDN, мы здесь не будем ее приводить.
Сама функция WSAEnumProtocols
, которая позволяет получить список всех протоколов, провайдеры которых установлены на компьютере, приведена в листинге 2.37.
Листинг 2.37. Функция WSAEnumProtocols
// ***** описание на C++ *****
int WSAEnumProtocols(LPINT lpiProtocols, LPWSAPROTOCOL_INFO lpProtocolBuffer, LPDWORD lpdwBufferLength);
// ***** Описание на Delphi *****
function WSAEnumProtocols(lpiProtocols: PInteger; lpProtocolBuffer: PWSAProtocolInfo; var BufferLength: DWORD): Integer;
Примечание
В старых версиях MSDN в описании этой функции есть небольшая опечатка: тип параметра lpdwBufferLength
назван LLPDWORD
вместо LPDWORD
.
Библиотека WS2_32.dll придерживается тех же правил насчет ANSI- и Unicode-вариантов функций, что и другие системные библиотеки (см. разд. 1.1.12), поэтому в ней нет функции с именем WSAEnumProtocols
, а есть WSAEnumProtocolsA
и WSAEnumProtocolsW
. Эти функции работают с разными вариантами структуры WSAPROTOCOL_INFO
, которые различаются типом элементов в последнем массиве — CHAR
или WCHAR
.
Параметр lpiProtocols
указывает на первый элемент массива, содержащего список протоколов, информацию о которых нужно получить. Если этот указатель равен nil
, то возвращается информация обо всех доступных протоколах. Параметр lpProtocolBuffer
содержит указатель на начало массива структур типа TWSAProtocolInfo
. Программа должна заранее выделить память под этот массив. Параметр BufferLength
при вызове должен содержать размер буфера lpProtocolBuffer
в байтах (именно размер в байтах, а не количество элементов). После завершения функции сюда помешается минимальный размер буфера, необходимый для размещения информации обо всех запрошенных протоколах. Если это значение больше переданного, функция завершается с ошибкой.
Если параметр lpiProtocols
не равен нулю, он должен содержать указатель на массив, завершающийся нулем. Следовательно, если количество протоколов, запрашиваемых программой, равно N , этот массив должен состоять из N +1 элементов, и первые N элементов должны содержать номера протоколов, а последний элемент — ноль.
В системе может быть установлено несколько провайдеров для одного протокола. В этом случае информация о каждом провайдере будет помещена в отдельный элемент массива. Из-за этого число задействованных элементов в массиве lpProtocolBuffer
может превышать количество протоколов, определяемых параметром lpiProtocols
.
К сожалению, полную информацию о том, каким протоколам какие номера соответствуют, в документации найти не удалось. Можно только сказать, что для получения информации о протоколе TCP в массив lpiProtocols
необходимо поместить константу IPPROTO_TCP
, о протоколе UDP — константу IPPROTO_UDP
.
Возвращаемое функцией значение равно числу протоколов, информация о которых помещена в массив, если функция выполнена успешно, и SOCKET_ERROR
, если при ее выполнении возникла ошибка. Конкретная ошибка определяется стандартным методом, с помощью WSAGetLastError
. Если массив lpProtocolBuffer
слишком мал для хранения всей требуемой информации, функция завершается с ошибкой WSAENOBUFS
.
WinSock 1 содержит аналогичную по возможности функцию EnumProtocols
, возвращающую массив структур PROTOCOL_INFO
. Эта структура содержит меньше информации о протоколе, чем WSAPROTOCOL_INFO
и, в отличие от последней, не используется никакими другими функциями WinSock. Несмотря на то, что функция EnumProtocols
и структура PROTOCOL_INFO
описаны в первой версии WinSock, модуль WinSock их не импортирует, при необходимости их нужно импортировать самостоятельно. Но функция EnumProtocols
считается устаревшей, использовать ее в новых приложениях не рекомендуется, поэтому практически всегда, за исключением редких случаев, требующих совместимости с WinSock 1, лучше выбрать более современную функцию WSAEnumProtocols
.
В этом разделе мы рассмотрим некоторые новые функции, появившиеся в WinSock 2. Большинство из них позволяет выполнять действия, уже знакомые нам из предыдущих разделов, но предоставляет большие возможности, чем стандартные сокетные функции.
Для создания сокета предназначена функция WSASocket
со следующим прототипом (листинг 2.38).
Листинг 2.38. Функция WSASocket
// ***** Описание на C++ *****
SOCKET WSASocket(int af, int SockType, int protocol, LPWSAPROTOCOL_INFO lpProtocolInfo, GROUP g, DWORD dwFlags);
Читать дальше
Конец ознакомительного отрывка
Купить книгу