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

       

Вызов recv имеет четыре параметра:


uses sockets;
Function Recv(sockfd:Longint; Var buffer; length,Flags:Longint):Longint;
Function Send(sockfd:Longint; Var buffer; length,Flags:Longint):Longint;
Вызов recv имеет четыре параметра: дескриптор файла filedes, из которого читаются данные, буфер buffer, в который они помещаются, размер буфера length и поле флагов flags.
Параметр flags указывает дополнительные опции получения данных. Его возможные значения определяются комбинациями следующих констант:



MSG_PEEK
Процесс может просматривать данные, не «получая» их
MSG_OOB
Обычные данные пропускаются. Процесс принимает только срочные данные, например, сигнал прерывания
MSG_WAITALL
Возврат из вызова recv произойдет только после получения всех данных

При аргументе flags равном нулю вызов send работает точно так же, как и вызов write, пересылая массив данных буфера buffer в сокет sockfd. Параметр length задает размер массива данных. Аналогично вызову recv параметр flags определяет опции передачи данных. Его возможные значения определяются комбинациями следующих констант:

MSG_OOB
Передать срочные (out of band) данные
MSG_DONTROUTE
При передаче сообщения игнорируются условия маршрутизации протокола более низкого уровня. Обычно это означает, что сообщение посылается по прямому, а не по самому быстрому маршруту (самый быстрый маршрут не обязательно прямой и может зависеть от текущего распределения нагрузки сети)

Теперь с помощью этих вызовов можно реализовать обработку данных на серверной стороне:
(* Серверный процесс *)
var
  c:char;
  client:tinetsockaddr;
  clientaddrlen:longint;
begin
  (* Приведенная выше инициализация сокета *)
  .
  .
  .
  while true do
  begin
    (* Принимает запрос на установку соединения *)
    newsockfd := accept (sockfd, client, clientaddrlen);
    if newsockfd = -1 then
    begin
      perror ('Ошибка вызова accept');
      continue;
    end;
    (* Создает дочерний процесс для работы с соединением *)


    if fork = 0 then
    begin
      (* Принимает данные *)
      while recv (newsockfd, c, 1, 0) > 0 do
      begin
        (* Преобразовывает строчный символ в прописной *)
        c := upcase (c);
        (* Пересылает символ обратно *)
        send (newsockfd, c, 1, 0);
      end;
    end;
  end;
end.
Напомним, что использование вызова fork позволяет серверу обслуживать несколько клиентов. Цикл работы клиентского процесса может быть реализован так:
(* Клиентский процесс *)
var
  sockfd:longint;
  c,rc:char;
begin
  (* Приведенная выше инициализация сокета и запрос
   * на установку соединения *)
  (* Обмен данными с сервером *)
  rc := #$a;
  while true do
  begin
    if rc = #$a then
      writeln ('Введите строчный символ');
    c:=char(getchar);
    send (sockfd, c, 1, 0);
    recv (sockfd, rc, 1, 0);
    write (rc)
  end;
end.

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