Лекция: Пересылка данных
Для сокетов типа SOCK_STREAM дескрипторы сокетов, полученные сервером посредством вызова accept() и клиентом с помощью вызова socked(), могут использоваться для чтения или записи. Для этого могут использоваться обычные вызовы read() и write(), либо специальные системные вызовы send() и recv(), позволяющие задавать дополнительные параметры пересылки данных по сети. Синхронизация данных при работе с сокетом аналогична передаче данных через программный канал.
#include<sys/types.h>
#include<sys/socket.h>
ssize_t recv (int sockfd, void *buffer, size_t length, int flags);
ssize_t send (int sockfd, const void *buffer, size_t length, int flags);
- socfd — дескриптор сокета, через который читаются или записываются данные;
- buffer — буфер, в который они помещаются или откуда отсылаются через сокет;
- length — размер буфера;
- flags — поле дополнительных опций при получении или передаче данных.
В случае успешного чтения/записи системные вызовы send() и recv() возвращают число прочитанных/отосланных байт, или -1 в случае ошибки; в случае разорванной связи (клиент разорвал TCP-соединение) вызов recv() (или read()) возвращают нулевое значение; если процесс пытается записать данные через разорванное TCP-соединение посредством write() или send(), то он получает сигнал SIGPIPE, который можно обработать, если предусмотрена обработка данного сигнала.
В случае flags = 0 вызовы send() и recv() полностью аналогичны системным вызовам read() и write().
Возможные комбинациями констант параметра flags системнного вызова send():
- MSG_PEEK Процесс может просматривать данные, не «получая» их;
- MSG_OOB Обычные данные пропускаются. Процесс принимает только срочные данные, например, сигнал прерывания;
- MSG_WAITALL Возврат из вызова recv произойдет только после получения всех данных.
Возможные комбинациями констант параметра flags системного вызова recv():
- MSG_OOB Передать срочные (out of band) данные;
- MSG_DONTROUTE При передаче сообщения игнорируются условия маршрутизации протокола более низкого уровня. Обычно это означает, что сообщение посылается по прямому, а не по самому быстрому маршруту (самый быстрый маршрут не обязательно прямой и может зависеть от текущего распределения нагрузки сети).
Данные операции выполняются и в программе сервера и в программе клиента.