function WSAConnect(S: TSocket; var Name: TSockAddr; NameLen: Integer; lpCollerData, lpCalleeData: PWSABuf; lpSQOS, lpGQOS: PQOS): Integer;
PWSABuf = ^TWSABuf;
TWSABuf = packed record
Len: Cardinal;
Buf: PChar;
end;
Функция WSAConnect
устанавливает соединение со стороны клиента. Ее первые три параметра совпадают с параметрами функции connect. Параметр lpCallerData
и lpCalleeData
служат для передачи данных от клиента серверу и от сервера клиенту при установлении соединения. Они оба являются указателями на структуру TWSABuf
тип TWSABuf
, которая содержит размер буфера Len
и указатель на буфер Buf
. Протоколы стека TCP/IP не поддерживают передачу данных при соединении, поэтому для TCP и UDP lpCallerData
и lpCalleeData
должны быть равны nil
. Параметры lpSQOS
и lpGQOS
— это указатели на структуры, с помощью которых программа передает свои требования к качеству обслуживания, причем параметр lpGQOS
связан с не поддерживаемым в настоящий момент групповым качеством и всегда должен быть равен nil
. Параметр lpSQOS
также должен быть равен nil
, если программа не предъявляет требований к качеству обслуживания. Так как рассмотрение качества обслуживания выходит за рамки данной книги, мы не приводим здесь определение структуры SQOS
, которое при необходимости легко найти в MSDN.
Между функциями connect
и WSAConnect
существует небольшое различие при работе с сокетами, не поддерживающими соединение. Как вы знаете из connect
может использоваться с такими сокетами для задания адреса отправки по умолчанию и автоматической фильтрации входящих пакетов. Для того чтобы отменить такое "соединение", нужно при вызове функции connect
указать адрес INADDR_ANY
и нулевой порт. В случае WSAConnect
для отмены "соединения" требуется, чтобы все без исключения поля структуры Name
, включая sin_family
, были нулевыми. Это сделано для того, чтобы обеспечить независимость от протокола: при любом протоколе для разрыва "соединения" должно устанавливаться одно и то же значение Name
.
Если программа не предъявляет требований к качеству обслуживания, то для протоколов TCP и UDP функция WSAConnect
не предоставляет никаких преимуществ по сравнению с connect
.
Функция accept
из стандартной библиотеки сокетов позволяет серверу извлечь из очереди соединений информацию о подключившемся клиенте и создать сокет для его обслуживания. Эти действия выполняются безусловно, для любых подключившихся клиентов. Если сервер допускает подключение не любых клиентов, а только тех, которые отвечают некоторым условиям (для протокола TCP эти условия могут заключаться в том, какие IP-адреса и какие порты допустимо использовать клиентам), сразу после установления соединения его приходится разрывать, если клиент не удовлетворяет этим условиям. Для упрощения этой операции в WinSock 2 предусмотрена функция WSAAccept
, прототип которой приведен в листинге 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).
TConditionProc
// ***** Описание на C++ *****
typedef (int*)(LPWSABUF lpCallerId, LPWSABUF lpCallerData, LPQOS lpSQOS, LPQOS lpGQOS, LPWSABUF lpCalleeId, LPWSABUF lpCalleeData, GROUP FAR* g, DWORD dwCallbackData) LPCONDITIONPROC;