Чтение онлайн

на главную - закладки

Жанры

О чём не пишут в книгах по Delphi

Григорьев Антон Борисович

Шрифт:

Из сказанного следует, что при использовании протокола TCP функция

WSAAccept
по сравнению с accept даёт два принципиальных преимущества: позволяет управлять качеством обслуживания и запрещать подключение нежелательных клиентов.

Некоторые протоколы поддерживают передачу информации не только при установлении связи, но и при её завершении. Для таких протоколов в WinSock2 предусмотрены функции

WSASendDisconnect
и
WSARecvDisconnect
. Так как протокол TCP не поддерживает передачу данных при закрытии соединения, для него эти функции не дают никаких преимуществ по сравнению с вызовом функции
shutdown
, поэтому мы не будем их здесь рассматривать.

Далее мы рассмотрим несколько новых

функций, унифицирующих работу с различными протоколами.

Функция

inet_addr
, как это уже упоминалось, жестко связана с протоколом IP и не имеет смысла для других протоколов. WinSock 2 предлагает вместо нее функцию
WSAStringToAddress
, имеющую следующий прототип (листинг 2.43).

Листинг 2.43. Функция
WSAStringToAddress

// ***** Описание на C++ *****

INT WSAStringToAddress(LPTSTR AddressString, INT AddressFamily, LPWSAPROTOCOL_INFO lpProtocolInfo, LPSOCKADDR lpAddress, LPINT lpAddressLength);

// ***** Описание на Delphi *****

function WSAStringToAddress(AddresString: PChar; AddressFamily: Integer; lpProtocolInfo: PWSAProtocolInfo; var Address: TSockAddr; var AddressLength: Integer): Integer;

Данная функция преобразует строку, задающую адрес сокета, в адрес, хранящийся в структуре

TSockAddr
. Параметр
AddressString
указывает на строку, хранящую адрес, параметр
AddressFamily
— на семейство адресов, для которого осуществляется трансляция. Если есть необходимость выбрать конкретный провайдер для протокола, в функцию может быть передан параметр
lpProtocolInfo
, в котором указан идентификатор провайдера. Если же программу устраивает провайдер по умолчанию, параметр
lpProtocolInfo
должен быть равен
nil
. Адрес возвращается через параметр
Address
. Параметр
AddressLength
при вызове функции должен содержать размер буфера, переданного через
Address
, а на выходе содержит реально использованное число байтов в буфере.

Функция возвращает 0 в случае успешного выполнения и

SOCKET_ERROR
— при ошибке. 

Допустимый формат строки определяется протоколом (некоторые протоколы вообще не поддерживают текстовую запись адреса, и для них функция

WSAStringToAddress
неприменима). Для семейства
AF_INET
, к которому относятся TCP и UDP, адрес может задаваться в виде "IP1.IP2.IP3.IР4:Port" или "IP1.IP2.IP3.IP4", где IРn — n– й компонент IP-адреса, записанною в виде 4-байтных полей,
Port
— номер порта. Если порт явно не указан, устанавливается нулевой номер порта.

Таким образом, чтобы в структуре

TSockAddr
оказался, например, адрес 192.168.100.217 и порт с номером 5000, необходимо выполнить следующий код (листинг 2.44).

Листинг 2.44. Пример использования функции
WSAStringToAddress

var

 Addr: TSockAddr;

 AddrLen: Integer;

begin

 AddrLen := SizeOf(Addr);

 WSAStringToAddress('192.168.100.217:5000', AF_INET, nil, Addr, AddrLen);

Существует также функция

WSAAddressToString
, обратная к
WSAStringToAddrеss
. Ее прототип приведен в листинге 2.45.

Листинг 2.45. Функция
WSAAddressToString

// ***** Описание на C++ *****

INT WSAAddressToString(LPSOCKADDR lpsaAddress, DWORD dwAddressLength, LWSAPROTOCOL_INFO lpProtocolInfo, LPTSTR lpszAddressString, LPDWORD lpdwAddressStringLength);

// *****
Описание на Delphi *****

function WSAAddressToString(var Address: TSockAddr; dwAddressLength: DWORD; lpProtocolInfo: PWSAProtocolInfo; lpszAddressString: PChar; var AddressStringLength: DWORD): Integer;

Как нетрудно догадаться по названию функции, она преобразует адрес, заданный структурой

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
.

Листинг 2.46. Функция
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.

Поделиться:
Популярные книги

Кодекс Крови. Книга IV

Борзых М.
4. РОС: Кодекс Крови
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Крови. Книга IV

Девятый

Каменистый Артем
1. Девятый
Фантастика:
боевая фантастика
попаданцы
9.15
рейтинг книги
Девятый

Кодекс Охотника. Книга XII

Винокуров Юрий
12. Кодекс Охотника
Фантастика:
боевая фантастика
городское фэнтези
аниме
7.50
рейтинг книги
Кодекс Охотника. Книга XII

Его маленькая большая женщина

Резник Юлия
Любовные романы:
современные любовные романы
эро литература
8.78
рейтинг книги
Его маленькая большая женщина

Саженец

Ланцов Михаил Алексеевич
3. Хозяин дубравы
Фантастика:
попаданцы
альтернативная история
фэнтези
5.00
рейтинг книги
Саженец

Свет во мраке

Михайлов Дем Алексеевич
8. Изгой
Фантастика:
фэнтези
7.30
рейтинг книги
Свет во мраке

(Не)свободные, или Фиктивная жена драконьего военачальника

Найт Алекс
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
(Не)свободные, или Фиктивная жена драконьего военачальника

Вамп

Парсиев Дмитрий
3. История одного эволюционера
Фантастика:
рпг
городское фэнтези
постапокалипсис
5.00
рейтинг книги
Вамп

Инвестиго, из медика в маги 2

Рэд Илья
2. Инвестиго
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Инвестиго, из медика в маги 2

Последняя Арена 4

Греков Сергей
4. Последняя Арена
Фантастика:
рпг
постапокалипсис
5.00
рейтинг книги
Последняя Арена 4

Хозяин Теней 2

Петров Максим Николаевич
2. Безбожник
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Хозяин Теней 2

Идеальный мир для Лекаря 8

Сапфир Олег
8. Лекарь
Фантастика:
юмористическое фэнтези
аниме
7.00
рейтинг книги
Идеальный мир для Лекаря 8

Неудержимый. Книга XI

Боярский Андрей
11. Неудержимый
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Неудержимый. Книга XI

Двойник Короля 2

Скабер Артемий
2. Двойник Короля
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Двойник Короля 2