16. Почти все реализации определяют константу SO_ACCEPTCONN
, но мы не описывали этот параметр. Прочтите [69], чтобы понять, зачем этот параметр существует.Глава 8
Основные сведения о сокетах UDP
8.1. Введение
Приложения, использующие TCP и UDP, фундаментально отличаются друг от друга, потому что UDP является ненадежным протоколом дейтаграмм, не ориентированным на установление соединения, и этим принципиально непохож на ориентированный на установление соединения и надежную передачу потока байтов TCP. Тем не менее есть случаи, когда имеет смысл использовать UDP вместо TCP. Подобные случаи мы рассматриваем в разделе 22.4. Некоторые популярные приложения построены с использованием UDP, например DNS (Domain Name System — система доменных имен), NFS (сетевая файловая система — Network File System) и SNMP (Simple Network Management Protocol — простой протокол управления сетью).
На рис. 8.1 показаны вызовы функций для типичной схемы клиент-сервер UDP. Клиент не устанавливает соединения с сервером. Вместо этого клиент лишь отправляет серверу дейтаграмму, используя функцию sendto
recvfrom
, которая ждет, когда придут данные от какого-либо клиента. Функция recvfrom
возвращает адрес клиента (для данного протокола) вместе с дейтаграммой, и таким образом сервер может отправить ответ именно тому клиенту, который прислал дейтаграмму.Рис. 8.1
. Функции сокета для модели клиент-сервер UDPРисунок 8.1 иллюстрирует временную диаграмму типичного сценария обмена UDP-дейтаграммами между клиентом и сервером. Мы можем сравнить этот пример с типичным обменом по протоколу TCP, изображенным на рис. 4.1.
В этой главе мы опишем новые функции, применяемые с сокетами UDP, — recvfrom
sendto
, и переделаем нашу модель клиент-сервер для применения UDP. Кроме того, мы рассмотрим использование функции connect с сокетом UDP и концепцию асинхронных ошибок.8.2. Функции recvfrom и sendto
Эти две функции аналогичны стандартным функциям read
write
, но требуют трех дополнительных аргументов.#include
ssize_t recvfrom(int
struct sockaddr *
ssize_t sendto(int
const struct sockaddr *
Первые три аргумента, sockfd
buff
и nbytes
, идентичны первым трем аргументам функций read
и write
: дескриптор, указатель на буфер, из которого производится чтение или в который происходит запись, и число байтов для чтения или записи.Мы расскажем об аргументе flags
recv
, send
, recvmsg
и sendmsg
, поскольку сейчас в нашем простом примере они не нужны. Пока мы всегда будем устанавливать аргумент flags
в нуль.Аргумент to для функции sendto
addrlen
. Функция recvform
заполняет структуру адреса сокета, на которую указывает аргумент from, записывая в нее протокольный адрес отправителя дейтаграммы. Число байтов, хранящихся в структуре адреса сокета, также возвращается вызывающему процессу в целом числе, на которое указывает аргумент addrlen
. Обратите внимание, что последний аргумент функции sendto
является целочисленным значением, в то время как последний аргумент функции recvfrom
— это указатель на целое значение (аргумент типа «значение-результат»).Последние два аргумента функции recvfrom аналогичны двум последним аргументам функции accept
sendto
аналогичны двум последним аргументам функции connect
: мы заполняем структуру адреса сокета протокольным адресом получателя дейтаграммы (в случае UDP) или адресом узла, с которым будет устанавливаться соединение (в случае TCP).