Как нетрудно догадаться по названию функции, она преобразует адрес, заданный структурой TSockAddr
, в строку. Адрес задаётся параметром Address
, параметр dwAddressLength
определяет длину буфера Address
. Необязательный параметр lpProtocolInfo
содержит указатель на структуру TWSAProtocolInfo
, с помощью которой можно определить, какой именно провайдер должен выполнить преобразование. Параметр lpszAddressString
содержит указатель на буфер, заранее выделенный программой, в который будет помещена строка. Параметр AddressStringLength
на входе должен содержать размер буфера, заданного параметром lpszAddressString
, а на выходе содержит длину получившейся строки.
Функция возвращает ноль в случае успеха и SOCKET_ERROR
— при ошибке. Ранее мы уже обсуждали различные форматы представления целых чисел, а также то, что формат, предусмотренный сетевым протоколом, может не совпадать с форматом, используемым узлом. Напомним, что для преобразования из сетевого формата в формат узла предназначены функции htons
, ntohs
, htonl
и ntohl
, привязанные к протоколам стека TCP/IP (другие протоколы могут иметь другой формат представления чисел). WinSock 2 предлагает аналоги этих функций WSAHtons
, WSANtohs
, WSAHtonl
и WSANtohl
, которые учитывают особенности конкретного протокола. Мы здесь рассмотрим только функцию WSANtohl
, преобразующую 32-битное целое из сетевого формата в формат узла. Остальные три функции работают аналогично. Листинг 2.46 содержит прототип функции WSANtohl
.
WSANtohl
// ***** Описание на C++ *****
int WSANtohl(SOCKET s, u_long netlong, u_long FAR *lphostlong);
// ***** Описание на Delphi *****
function WSANtohl(S: TSocket; NetLong: Cardinal; var HostLong: Cardinal): Integer;
Параметр S
задает сокет, для которого осуществляется преобразование. Так как сокет всегда связан с конкретным протоколом, этого параметра достаточно, чтобы библиотека могла определить, по какому закону преобразовывать число из сетевого формата в формат хоста. Число в сетевом формате задаётся параметром NetLong
, результат преобразования помещается в параметр HostLong
.
Функция возвращает ноль в случае успешного выполнения операции и SOCKET_ERROR
— при ошибке.
Если программа работает только с протоколами стека TCP/IP, старые варианты функций удобнее новых, потому что возвращают непосредственно результат преобразования, который можно использовать в выражениях. При работе с новыми функциями для получения результата следует заводить отдельную переменную, поэтому эти функции целесообразны тогда, когда программа должна единым образом работать с разными протоколами. Последняя функция, которую мы здесь рассмотрим, не имеет прямых аналогов среди старых функций. Называется она WSADuplicateSocket
и служит для копирования дескриптора сокета в другой процесс. Прототип функции WSADuplicateSocket
приведен в листинге 2.47.
WSADuplicateSocket
// ***** Описание на C++ *****
int WSADuplicateSocket(SOCKET s, DWORD dwProcessId, LPWSAPROTOCOL_INFO lpProtocolInfo);
// ***** Описание на Delphi *****
function WSADuplicateSocket(S: TSocket; dwProcessID: DWORD; var ProtocolInfo: TWSAProtocolInfo): Integer;
Параметр S
задает сокет, дескриптор которого нужно скопировать, параметр dwProcessID
— идентификатор процесса, для которого предназначена копия, функция помещает в структуру ProtocolInfo
информацию, необходимую для создания копии дескриптора другим процессом. Затем эта структура должна быть каким-то образом передана другому процессу, который передаст ее в функцию WSASocket
и получит свою копию дескриптора для работы с данным сокетом.