Книга: 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-12fgets
, отправка строки серверу с помощью функции sendto
, чтение отраженного ответа сервера с помощью функции recvfrom
и помещение отраженной строки в стандартный поток вывода с помощью функции fputs
.
Наш клиент не запрашивал у ядра присваивания динамически назначаемого порта своему сокету (тогда как для клиента TCP это имело место при вызове функции connect
). В случае сокета UDP при первом вызове функции sendto
ядро выбирает динамически назначаемый порт, если с этим сокетом еще не был связан никакой локальный порт. Как и в случае TCP, клиент может вызвать функцию bind явно, но это делается редко.
Обратите внимание, что при вызове функции recvfrom
в качестве пятого и шестого аргументов задаются пустые указатели. Таким образом мы сообщаем ядру, что мы не заинтересованы в том, чтобы знать, кто отправил ответ. Существует риск, что любой процесс, находящийся как на том же узле, так и на любом другом, может отправить на IP-адрес и порт клиента дейтаграмму, которая будет прочитана клиентом, предполагающим, что это ответ сервера. Эту ситуацию мы рассмотрим в разделе 8.8.
Как и в случае функции сервера dg_echo
, функция клиента dg_cli
является не зависящей от протокола, но функция main клиента зависит от протокола. Функция main размещает в памяти и инициализирует структуру адреса сокета, относящегося к определенному типу протокола, а затем передает функции dg_cli
указатель на структуру вместе с ее размером.
- 8.1. Введение
- 8.2. Функции recvfrom и sendto
- 8.3. Эхо-сервер UDP: функция main
- 8.4. Эхо-сервер UDP: функция dg_echo
- 8.5. Эхо-клиент UDP: функция main
- 8.6. Эхо-клиент UDP: функция dg_cli
- 8.7. Потерянные дейтаграммы
- 8.8. Проверка полученного ответа
- 8.9. Запуск клиента без запуска сервера
- 8.10. Итоговый пример клиент-сервера UDP
- 8.11. Функция connect для UDP
- 8.12. Функция dg_cli (продолжение)
- 8.13. Отсутствие управления потоком в UDP
- 8.14. Определение исходящего интерфейса для UDP
- 8.15. Эхо-сервер TCP и UDP, использующий функцию select
- 8.16. Резюме
- Упражнения
- 8.14. Определение исходящего интерфейса для UDP
- Совместимость клиентов и серверов различных версий
- Клиенты 3-го диалекта
- 2.1.3. Функция getopt_long()
- Аватар идеального клиента
- Группировка по встроенным функциям и UDF
- Определение версии клиента
- Снятие ответственности с клиента
- SERVER CLIENT MAPPING
- 19.1.1. Функция jQuery()
- Приложение 21 Образец должностной инструкции начальника отдела по работе с сетевыми клиентами
- UDP characteristics