Системное программирование в UNIX средствами Free Pascal

       

Системному вызову 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ответствующую адресу локального компьютера.
Теперь имеется серверный процесс, способный переходить в режим приёма соединений и принимать запросы на установку соединений. Рассмотрим, как клиент должен обращаться к серверу.

Содержание раздела