Читаем UNIX: разработка сетевых приложений полностью

Обе функции возвращают в качестве значения функции длину данных, которые были прочитаны или записаны. При типичном использовании функции recvfrom с протоколом дейтаграмм возвращаемое значение — это объем пользовательских данных в полученной дейтаграмме.

Дейтаграмма может иметь нулевую длину. В случае UDP при этом возвращается дейтаграмма IP, содержащая заголовок IP (обычно 20 байт для IPv4 или 40 байт для IPv6), 8-байтовый заголовок UDP и никаких данных. Это также означает, что возвращаемое из функции recvfrom нулевое значение вполне приемлемо для протокола дейтаграмм: оно не является признаком того, что собеседник закрыл соединение, как это происходит при возвращении нулевого значения из функции read на сокете TCP. Поскольку протокол UDP не ориентирован на установление соединения, то в нем и не существует такого события, как закрытие соединения.

Если аргумент from функции recvfrom является пустым указателем, то соответствующий аргумент длины (addrlen) также должен быть пустым указателем, и это означает, что нас не интересует адрес отправителя данных.

И функция recvfrom, и функция sendto могут использоваться с TCP, хотя обычно в этом нет необходимости.

8.3. Эхо-сервер UDP: функция main

Теперь мы переделаем нашу простую модель клиент-сервер из главы 5, используя UDP. Диаграмма вызовов функций в программах наших клиента и сервера UDP показана на рис. 8.1. На рис. 8.2 представлены используемые функции. В листинге 8.1[1] показана функция сервера main.

Рис. 8.2. Простая модель клиент-сервер, использующая UDP

Листинг 8.1. Эхо-сервер UDP

//udpcliserv/udpserv01.с

 1 #include "unp.h"


 2

 3 intmain(int argc, char **argv)

 4 {

 5  int sockfd;

 6  struct sockaddr_in servaddr, cliaddr;


 7  sockfd = Socket(AF_INET, SOCK_DGRAM, 0);


 8  bzero(&servaddr, sizeof(servaddr));

 9  servaddr.sin_family = AF_INET;

10  servaddr.sin_addr.s_addr = htonl(INADDR_ANY);

11  servaddr.sin_port = htons(SERV_PORT);


12  Bind(sockfd, (SA*)&servaddr, sizeof(servaddr));


13  dg_echo(sodkfd, (SA*)&cliaddr, sizeof(cliaddr));

14 }

Создание сокета UDP, связывание с заранее известным портом при помощи функции bind

7-12 Мы создаем сокет UDP, задавая в качестве второго аргумента функции socket значение SOCK_DGRAM (сокет дейтаграмм в протоколе IPv4). Как и в примере сервера TCP, адрес IPv4 для функции bind задается как INADDR_ANY, а заранее известный номер порта сервера — это константа SERV_PORT из заголовка unp.h.

13 Затем вызывается функция dg_echo для обработки клиентского запроса сервером.

8.4. Эхо-сервер UDP: функция dg_echo

В листинге 8.2 показана функция dg_echo.

Листинг 8.2. Функция dg_echo: отражение строк на сокете дейтаграмм

//lib/dg_echo.c

 1 #include "unp.h"


 2 void

 3 dg_echo(int sockfd, SA *pcliaddr, socklen_t clilen)

 4 {

 5  int n;

 6  socklen_t len;

 7  char mesg[MAXLINE];


 8  for (;;) {

 9   len = clilen;

10   n = Recvfrom(sockfd, mesg, MAXLINE, 0, pcliaddr, &len);


11   Sendto(sockfd, mesg, n, 0, pcliaddr, len);

12  }

13 }

Чтение дейтаграммы, отражение отправителю

8-12 Эта функция является простым циклом, в котором очередная дейтаграмма, приходящая на порт сервера, читается функцией recvfrom и с помощью функции sendto отправляется обратно.

Несмотря на простоту этой функции, нужно учесть ряд важных деталей. Во- первых, эта функция никогда не завершается. Поскольку UDP — это протокол, не ориентированный на установление соединения, в нем не существует никаких аналогов признака конца файла, используемого в TCP.

Во-вторых, эта функция позволяет создать последовательный сервер, а не параллельный, который мы получали в случае TCP. Поскольку нет вызова функции fork, один процесс сервера выполняет обработку всех клиентов. В общем случае большинство серверов TCP являются параллельными, а большинство серверов UDP — последовательными.

Перейти на страницу:

Все книги серии Мастер-класс

Секреты резьбы по дереву
Секреты резьбы по дереву

Изделия из древесины и материалов, имитирующих ее текстуру, привычным образом окружают нас в повседневной жизни, поэтому мы относимся к ней как к чему-то обыденному. Но как только ее коснется умелая рука мастера резьбы по дереву, рождается произведение искусства и раскрываются такие качества древесины, как богатая фактура, разнообразие цветов, особая теплота. Эта книга поможет читателю открыть для себя удивительный мир творчества и познать секреты резьбы по дереву. Автор надеется, что начинающие резчики найдут в ней интересный и полезный материал, который позволит им стать мастерами. В приложении представлены рисунки орнаментов и различных узоров, которые на первых порах можно копировать, а по мере приобретения навыка на их основе разрабатывать свои образцы.

Галина Алексеевна Серикова

Сделай сам / Хобби и ремесла / Руководства / Дом и досуг / Словари и Энциклопедии

Похожие книги