Скачиваний:
56
Добавлен:
08.01.2014
Размер:
2.6 Mб
Скачать

Описание

uses sockets;

Function Bind(sockfd:Longint; Var address; add_len:Longint):Boolean;

Function Bind(sockfd:longint; const address:string):boolean;

Первый параметр, sockfd, является дескриптором файла сокета, созданным с помощью вызова socket, а второй – указателем на обобщенную структуру адреса сокета или адрес в форме строки. В рассматриваемом примере данные пересылаются по сети, поэтому в действительности в качестве этого параметра будет задан адрес структуры TInetSockAddr, содержащей информацию об адресе нашего сервера. Последний параметр содержит размер указанной структуры адреса сокета. В случае успешного завершения вызова bind он возвращает значение 0. В случае ошибки, например, если сокет для этого адреса уже существует, вызов bind возвращает значение -1. Переменная linuxerror будет иметь при этом значение Sys_EADDRINUSE.

10.5.2. Включение приема tcp-соединений

После выполнения связывания с адресом и перед тем, как какой-либо клиент сможет подключиться к созданному сокету, сервер должен включить прием соединений. Для этого служит вызов listen.

Описание

uses sockets;

Function Listen(sockfd, queue_size:Longint):Boolean;

Параметр sockfd имеет то же значение, что и в предыдущем вызове. В очереди сервера может находиться не более queue_size запросов на соединение. (Спецификация XSI определяет минимальное ограничение сверху на длину очереди равное пяти.)

10.5.3. Прием запроса на установку tcp-соединения

Когда сервер получает от клиента запрос на соединение, он должен создать новый сокет для работы с новым соединением. Первый же сокет используется только для установки соединения. Дополнительный сокет создается при помощи вызова accept, принимающего очередное соединение.

Описание

uses sockets;

Function Accept(sockfd:Longint;Var address;Var add_len:Longint):Longint;

Function Accept(sockfd:longint;var address:string;

var SockIn,SockOut:text):Boolean;

Function Accept(sockfd:longint;var address:string;

var SockIn,SockOut:File):Boolean;

Function Accept(sockfd:longint;var address:TInetSockAddr;

var SockIn,SockOut:File):Boolean;

Системному вызову accept передается дескриптор сокета, для которого ведется прием соединений. Возвращаемое значение соответствует идентификатору нового сокета, который будет использоваться для связи. Параметр address заполняется информацией о клиенте. Так как связь использует соединение, адрес клиента знать не обязательно, поэтому можно присвоить параметру address значение nil. Если значение address не равно nil, то переменная, на которую указывает параметр add_len, первоначально должна содержать размер структуры адреса, заданной параметром address. После возврата из вызова accept переменная add_len будет содержать реальный размер записанной структуры.

Вторая, третья и четвертая формы вызова accept эквивалентны вызову первой с последующим использованием функции Sock2Text, преобразующей сокет sockfd в две файловые переменные типа Text, одна из которых отвечает за чтение из сокета (SockIn), а другая – за запись в сокет (SockOut).

После подстановки вызовов bind, listen и accept текст программы сервера примет вид:

(* Серверный процесс *)

uses sockets,stdio,linux;

const

SIZE=sizeof(tinetsockaddr);

(* Инициализация сокета Internet с номером порта 7000

* и локальным адресом, заданным в постоянной INADDR_ANY *)

server:tinetsockaddr = (family:AF_INET; port:7000; addr:INADDR_ANY);

var

newsockfd:longint;

sockfd:longint;

begin

(* Создает сокет *)

sockfd := socket (AF_INET, SOCK_STREAM, 0);

if sockfd = -1 then

begin

perror ('Ошибка вызова socket');

halt (1);

end;

(* Связавает адрес с сокетом *)

if not bind (sockfd, server, SIZE) then

begin

perror ('Ошибка вызова bind');

halt (1);

end;

(* Включает прием соединений *)

if not listen (sockfd, 5) then

begin

perror ('ошибка вызова listen');

halt (1);

end;

while true do

begin

(* Принимает очередной запрос на соединение *)

newsockfd := accept (sockfd, client, clientaddrlen);

if newsockfd = -1 then

begin

perror ('Ошибка вызова accept');

continue;

end;

(*

Создает дочерний процесс для работы с соединением.

Если это дочерний процесс,

то в цикле принимает данные от клиента

и посылает ему ответы.

*)

end;

end.

Обратите внимание на то, что сервер использует константу INADDR_ANY, coответствующую адресу локального компьютера.

Теперь имеется серверный процесс, способный переходить в режим приёма соединений и принимать запросы на установку соединений. Рассмотрим, как клиент должен обращаться к серверу.

Соседние файлы в папке Полищук, Семериков. Системное программирование в UNIX средствами Free Pascal