Первая функция, необходимая для большинства сетевых программ, — listen. Когда серверная программа открыла порт и ожидает соединения со стороны клиента, то она должна вызвать эту функцию. Функция служит для начала прослушивания порта на случай подключения к нему со стороны клиента. Вот так выглядит эта функция в WinSock2:
function listen( s: TSocket; backlog: Integer ): Integer; stdcall;
o Первый параметр s — дескриптор гнезда или сокет.
o Второй параметр backlog — максимально допустимое число запросов, ожидающих обработки. Если этот параметр равен SOMAXCONN, то ядро само установит максимально возможное для него значение.
В большинстве случаев параметр blocklog зависит от установленного в системе параметра "максимальное количество подключений". Если вы используете Windows 95/98, то этот параметр регулируется в настройках сети.
Следующая функция называется accept. Она служит для подтверждения соединения сервером. Эта функция принимает запросы на подключение, поступающие на вход процесса-сервера:
function accept ( const s: TSocket; var addr: TSockAddr; var addrlen: Integer ): TSocket; stdcall;
o Первый параметр s — это все тот же дескриптор гнезда/сокета.
o addr — указатель на структуру, в котором ядро возвращает адрес подключаемого клиента.
o addrlen — размер адреса.
После завершения выполнения функции ядро записывает в переменную addrlen длину параметра addr. Функция возвращает новый дескриптор гнезда, отличный от дескриптора s. Процесс-сервер может продолжать слежение за состоянием объявленного гнезда, поддерживая связь с клиентом по отдельному каналу.
|
|
Рис. 5.10. Соединение клиента с сервером
Мы закончили рассматривать функции, необходимые вам для соединения клиента и сервера. Теперь мы начнем знакомиться с передачей данных. И первой на очереди стоит функция отправки пакетов, потому что для того, чтобы что-то принять, необходимо сначала отправить. И поможет нам в отправке пакетов функция send.
function send ( s: TSocket; var Buf; len, flags: Integer ) : Integer; stdcall;
Рассмотрим каждый параметр в отдельности:
o s — как всегда, это дескриптор гнезда;
o buf — указатель на посылаемые данные;
o len — размер данных;
o flags — флаги, установки.
Функция возвращает количество фактически переданных байтов.
Параметр flags может содержать значения: MSG_DONTROUTE — определяет, что данные не должны быть подчинены маршрутизации, MSG_OOB — послать данные out-of-band ("через таможню"), если посылаемые данные не учитываются в общем информационном обмене между взаимодействующими процессами.
Длина сообщения не должна превышать значения в SO_MAX_MSG_SIZE. Прием данных осуществляется функцией recv:
function recv(s: TSocket; var Buf; len, flags: Integer ): Integer; stdcall;
Параметры практически те же:
o buf — массив для приема данных.
o len — ожидаемый объем данных.
o flags — могут быть установлены таким образом, что поступившее сообщение после чтения и анализа его содержимого не будет удалено из очереди, или настроены на получение данных out-of-band.
· MSG_PEEK — данные будут скопированы в буфер, но не удалены из
входной очереди;
· MSG_OOP — то же, что и в функции send.
Функция recv возвращает количество байтов, фактически переданных пользовательской программе.
Для датаграммных версий используются функции sendto и recvfrom. Обе функции работают так же, как и в send и recv, только в качестве дополнительных параметров указываются адреса.
Теперь мы научились получать соединения, посылать данные, осталось только научиться закрывать соединения. Функция shutdown закрывает гнездовую связь.