Вызов 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.