Книга: UNIX: разработка сетевых приложений

8.6. Эхо-клиент UDP: функция dg_cli

8.6. Эхо-клиент UDP: функция dg_cli

В листинге 8.4 показана функция dg_cli, которая выполняет большую часть работы на стороне клиента.

Листинг 8.4. Функция dg_cli: цикл обработки клиента

//lib/dg_cli.c
 1 #include "unp.h"
 2 void
 3 dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)
 4 {
 5  int n;
 6  char sendline[MAXLINE], recvline[MAXLINE + 1];
 7  while (Fgets(sendline, MAXLINE, fp) != NULL) {
 8   Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen);
 9   n = Recvfrom(sockfd, recvline, MAXLINE, 0, NULL, NULL);
10   recvline[n] = 0; /* завершающий нуль */
11   Fputs(recvline, stdout);
12  }
13 }
7-12
 В цикле обработки на стороне клиента имеется четыре шага: чтение строки из стандартного потока ввода при помощи функции fgets, отправка строки серверу с помощью функции sendto, чтение отраженного ответа сервера с помощью функции recvfrom и помещение отраженной строки в стандартный поток вывода с помощью функции fputs.

Наш клиент не запрашивал у ядра присваивания динамически назначаемого порта своему сокету (тогда как для клиента TCP это имело место при вызове функции connect). В случае сокета UDP при первом вызове функции sendto ядро выбирает динамически назначаемый порт, если с этим сокетом еще не был связан никакой локальный порт. Как и в случае TCP, клиент может вызвать функцию bind явно, но это делается редко.

Обратите внимание, что при вызове функции recvfrom в качестве пятого и шестого аргументов задаются пустые указатели. Таким образом мы сообщаем ядру, что мы не заинтересованы в том, чтобы знать, кто отправил ответ. Существует риск, что любой процесс, находящийся как на том же узле, так и на любом другом, может отправить на IP-адрес и порт клиента дейтаграмму, которая будет прочитана клиентом, предполагающим, что это ответ сервера. Эту ситуацию мы рассмотрим в разделе 8.8.

Как и в случае функции сервера dg_echo, функция клиента dg_cli является не зависящей от протокола, но функция main клиента зависит от протокола. Функция main размещает в памяти и инициализирует структуру адреса сокета, относящегося к определенному типу протокола, а затем передает функции dg_cli указатель на структуру вместе с ее размером.

Оглавление книги


Генерация: 1.610. Запросов К БД/Cache: 3 / 1
поделиться
Вверх Вниз