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

на главную

Жанры

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

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

Шрифт:

Между функциями

connect
и
WSAConnect
существует небольшое различие при работе с сокетами, не поддерживающими соединение. Как вы знаете из разд. 2.1.9, функция
connect
может использоваться с такими сокетами для задания адреса отправки по умолчанию и автоматической фильтрации входящих пакетов. Для того чтобы отменить такое "соединение", нужно при вызове функции
connect
указать адрес
INADDR_ANY
и нулевой порт. В случае
WSAConnect
для отмены "соединения" требуется, чтобы все без исключения поля структуры
Name
, включая
sin_family
, были нулевыми. Это сделано для того, чтобы обеспечить независимость
от протокола: при любом протоколе для разрыва "соединения" должно устанавливаться одно и то же значение
Name
.

Если программа не предъявляет требований к качеству обслуживания, то для протоколов TCP и UDP функция

WSAConnect
не предоставляет никаких преимуществ по сравнению с
connect
.

Функция

accept
из стандартной библиотеки сокетов позволяет серверу извлечь из очереди соединений информацию о подключившемся клиенте и создать сокет для его обслуживания. Эти действия выполняются безусловно, для любых подключившихся клиентов. Если сервер допускает подключение не любых клиентов, а только тех, которые отвечают некоторым условиям (для протокола TCP эти условия могут заключаться в том, какие IP-адреса и какие порты допустимо использовать клиентам), сразу после установления соединения его приходится разрывать, если клиент не удовлетворяет этим условиям. Для упрощения этой операции в WinSock 2 предусмотрена функция
WSAAccept
, прототип которой приведен в листинге 2.40. 

Листинг 2.40. Функция
WSAAccept

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

SOCKET WSAAccept(SOCKET S, struct sockaddr FAR* addr, LPINT addrlen, LPCONDITIONPROC lpfnCondition, dwCallbackData);

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

function WSAAccept( S: TSocket; Addr: PSockAddr; AddrLen: PInteger; lpfnCondition: TConditionProc; dwCallbackData: DWORD): TSocket;

По сравнению с уже известной нам функцией

accept
функция
WSAAccept
имеет два новых параметра:
lpfnCondition
и
dwCallbackData
.
lpfnCondition
является указателем на функцию обратного вызова. Эта функция объявляется и реализуется программой.
WSAAccept
вызывает ее внутри себя и в зависимости от ее результата принимает или отклоняет соединение. Параметр
dwCallbackData
не имеет смысла для самой функции
WSAAccept
и передается без изменений в функцию обратного вызова. Тип
TConditionProc
должен быть объявлен следующим образом (листинг 2.41).

Листинг 2.41. Тип
TConditionProc

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

typedef (int*)(LPWSABUF lpCallerId, LPWSABUF lpCallerData, LPQOS lpSQOS, LPQOS lpGQOS, LPWSABUF lpCalleeId, LPWSABUF lpCalleeData, GROUP FAR* g, DWORD dwCallbackData) LPCONDITIONPROC;

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

TConditionProc = function(lpCallerId, lpCallerData: PWSABuf; lpSQOS, lpGQOS: PQOS; lpCalleeID, lpCalleeData: PWSABuf; g: PGroup; dwCallbackData: DWORD): Integer; stdcall;

Параметр

lpCallerId
указывает на буфер, в котором хранится адрес подключившегося клиента. При работе со стеком TCP/IP
lpCallerId^.Len
будет равен
SizeOf(TSockAddr)
, a
lpCallerId^.Buf
будет указывать на структуру
TSockAddr
, содержащую адрес клиента. Параметр
lpCallerData
определяет буфер, в котором хранятся данные, переданные клиентом при соединении. Как уже отмечалось, протоколы стека TCP/IP не поддерживают передачу данных при соединении, поэтому для них этот параметр будет равен nil. Параметры
lpSQOS
и
lpGQOS
задают требуемое клиентом качество обслуживания для сокета и для группы соответственно.
Так как группы сокетов в текущей реализации WinSock не поддерживаются, параметр
lpGQOS
будет равен
nil
. Параметр
lpSQOS
тоже будет равен
nil
, если клиент не задал качество обслуживания при соединении.

Параметр

lpCalleeId
содержит адрес интерфейса, принявшего соединение (поля структуры при этом используются так же, как у параметра
lpCallerId
). Ранее уже обсуждалось, что сокет, привязанный к адресу
INADDR_ANY
, прослушивает все сетевые интерфейсы, имеющиеся на компьютере, но каждое подключение, созданное с его помощью, использует конкретный интерфейс. Параметр
lpCalleeId
содержит адрес, привязанный к конкретному соединению. Параметр
lpCalleeData
указывает на буфер, в который сервер может поместить данные для отправки клиенту. Этот параметр также не имеет смысла для протокола TCP, не поддерживающего отправку данных при соединении.

Параметр

g
выходной, он позволяет управлять присоединением создаваемого функцией
WSAAccept
сокета к группе. Параметр, как и все, связанное с группами, зарезервирован для использования в будущем.

Примечание

Если вы пользуетесь старой версией MSDN, то можете не обнаружить там описания параметра

g
— оно там отсутствует. Видимо, просто по ошибке.

И наконец, через параметр

dwCallbackData
в функцию обратного вызова передается значение параметра
dwCallbackData
, переданное в функцию
WSAAccept
. Программист должен сам решить, как ему интерпретировать это значение.

Функция должна вернуть

CF_ACCEPT
(0), если соединение принимается,
CF_REJECT
(1), если оно отклоняется, и
CF_DEFER
(2), если решение о разрешении или запрете соединения откладывается. Если функция обратного вызова вернула
CF_REJECT
, to
WSAAccept
завершается с ошибкой
WSAECONNREFUSED
, если
CF_DEFER
— то с ошибкой
WSATRY_AGAIN
(в последнем случае соединение остаётся в очереди, и информация о нем вновь будет передана в функцию обратного вызова при следующем вызове
WSAAccept
). Обе эти ошибки не фатальные, сокет остается в режиме ожидания соединения и может принимать подключения от новых клиентов.

Ранее уже обсуждалось, что функция

connect
на стороне клиента считается успешно завершенной тогда, когда соединение встало в очередь, а не тогда, когда оно реально принято сервером через функцию
accept
. По умолчанию для клиента, соединение с которым сервер отклонил, нет разницы, вызвал ли сервер функцию
WSAAccept
и сразу отклонил соединение, или установил его с помощью
accept
, а потом разорвал. В обоих случаях клиент сначала получит информацию об успешном соединении с сервером, а потом это соединение будет разорвано. Но при использовании
WSAAccept
можно установить такой режим работы, когда сначала выполняется функция. заданная параметром
lpCondition
, и лишь потом клиенту отправляется разрешение или запрет на подключение. Включается этот режим установкой параметра слушающего сокета
SO_CONDITIONAL_ACCEPT
, что иллюстрирует листинг 2.42.

Листинг 2.42. Включение режима ожидания реального подключения

var

 Cond: BOOL;

begin

 Cond := True;

 setsockopt(S, SOL_SOCKET, SO_CONDITIONAL_ACCEPT, PChar(@Cond), SizeOf(Cond));

Этот режим снижает нагрузку на сеть и повышает устойчивость сервера против DoS-атак, заключающихся в многократном подключении-отключении посторонних клиентов, поэтому в серьезных серверах рекомендуется использовать эту возможность.

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

Барон играет по своим правилам

Ренгач Евгений
5. Закон сильного
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Барон играет по своим правилам

Сердце Дракона. нейросеть в мире боевых искусств (главы 1-650)

Клеванский Кирилл Сергеевич
Фантастика:
фэнтези
героическая фантастика
боевая фантастика
7.51
рейтинг книги
Сердце Дракона. нейросеть в мире боевых искусств (главы 1-650)

Герцогиня в ссылке

Нова Юлия
2. Магия стихий
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Герцогиня в ссылке

Ну привет, заучка...

Зайцева Мария
Любовные романы:
эро литература
короткие любовные романы
8.30
рейтинг книги
Ну привет, заучка...

На Ларэде

Кронос Александр
3. Лэрн
Фантастика:
фэнтези
героическая фантастика
стимпанк
5.00
рейтинг книги
На Ларэде

Сердце Дракона. Том 12

Клеванский Кирилл Сергеевич
12. Сердце дракона
Фантастика:
фэнтези
героическая фантастика
боевая фантастика
7.29
рейтинг книги
Сердце Дракона. Том 12

Истинная поневоле, или Сирота в Академии Драконов

Найт Алекс
3. Академия Драконов, или Девушки с секретом
Любовные романы:
любовно-фантастические романы
6.37
рейтинг книги
Истинная поневоле, или Сирота в Академии Драконов

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

Винокуров Юрий
6. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга VI

Гардемарин Ее Величества. Инкарнация

Уленгов Юрий
1. Гардемарин ее величества
Фантастика:
городское фэнтези
попаданцы
альтернативная история
аниме
фантастика: прочее
5.00
рейтинг книги
Гардемарин Ее Величества. Инкарнация

Сама себе хозяйка

Красовская Марианна
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Сама себе хозяйка

Душелов. Том 3

Faded Emory
3. Внутренние демоны
Фантастика:
альтернативная история
аниме
фэнтези
ранобэ
хентай
5.00
рейтинг книги
Душелов. Том 3

Газлайтер. Том 10

Володин Григорий
10. История Телепата
Фантастика:
боевая фантастика
5.00
рейтинг книги
Газлайтер. Том 10

Стеллар. Заклинатель

Прокофьев Роман Юрьевич
3. Стеллар
Фантастика:
боевая фантастика
8.40
рейтинг книги
Стеллар. Заклинатель

Возвышение Меркурия. Книга 5

Кронос Александр
5. Меркурий
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Возвышение Меркурия. Книга 5