Чтение онлайн

на главную - закладки

Жанры

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

13 }

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

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

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

Во-вторых, эта функция позволяет создать

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

Для сокета на уровне UDP происходит неявная буферизация дейтаграмм в виде очереди. Действительно, у каждого сокета UDP имеется буфер приема, и каждая дейтаграмма, приходящая на этот сокет, помещается в его буфер приема. Когда процесс вызывает функцию

recvfrom
, очередная дейтаграмма из буфера возвращается процессу в порядке FIFO (First In, First Out — первым пришел, первым обслужен). Таким образом, если множество дейтаграмм приходит на сокет до того, как процесс может прочитать данные, уже установленные в очередь для сокета, то приходящие дейтаграммы просто добавляются в буфер приема сокета. Но этот буфер имеет ограниченный размер. Мы обсуждали этот размер и способы его увеличения с помощью параметра сокета
SO_RCVBUF
в разделе 7.5.

На рис. 8.3 показано обобщение нашей модели TCP клиент-сервер из главы 5, когда два клиента устанавливают соединения с сервером.

Рис. 8.3. Обобщение модели TCP клиент-сервер с двумя клиентами

Здесь имеется два присоединенных сокета, и каждый из присоединенных сокетов на узле сервера имеет свой собственный буфер приема. На рис. 8.4 показан случай, когда два клиента отправляют дейтаграммы серверу UDP.

Рис. 8.4. Обобщение модели UDP клиент-сервер с двумя клиентами

Существует только один процесс сервера, и у него имеется один сокет, на который сервер получает все приходящие дейтаграммы и с которого отправляет все ответы. У этого сокета имеется буфер приема, в который помещаются все приходящие дейтаграммы.

Функция

main
в листинге 8.1 является зависящей от протокола (она создает сокет семейства
AF_INET
, а затем выделяет и инициализирует структуру адреса сокета IPv4), но функция
dg_echo
от протокола не зависит. Причина, по которой функция
dg_echo
не зависит от протокола, заключается в том, что вызывающий процесс (в нашем случае функция
main
) должен разместить в памяти структуру адреса сокета корректного размера, и указатель на эту структуру вместе с ее размером передаются в качестве аргументов функции
dg_echo
. Функция
dg_echo
никогда не углубляется в эту структуру: она просто передает указатель на нее функциям
recvfrom
и
sendto
. Функция
recvfrom
заполняет эту структуру, вписывая в нее IP-адрес и номер порта клиента, и поскольку тот же указатель (
pcliaddr
) затем передается функции
sendto
в качестве адреса получателя, таким образом дейтаграмма отражается обратно клиенту, отправившему дейтаграмму.

8.5. Эхо-клиент UDP:

функция main

Функция

main
клиента UDP показана в листинге 8.3.

Листинг 8.3. Эхо-клиент UDP

//udpcliserv/udpcli01.c

1 #include "unp.h"

2 int

3 main(int argc, char **argv)

4 {

5 int sockfd;

6 struct sockaddr_in servaddr;

7 if (argc != 2)

8 err_quit("usage: udpcli <Ipaddress>");

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

10 servaddr.sin_family = AF_INET;

11 servaddr.sin_port = htons(SERV_PORT);

12 Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);

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

14 dg_cli(stdin, sockfd, (SA*)&servaddr, sizeof(servaddr));

15 exit(0);

16 }

Заполнение структуры адреса сокета адресом сервера

9-12
Структура адреса сокета IPv4 заполняется IP-адресом и номером порта сервера. Эта структура будет передана функции
dg_cli
. Она определяет, куда отправлять дейтаграммы.

13-14
Создается сокет 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
.

Поделиться:
Популярные книги

Восход. Солнцев. Книга X

Скабер Артемий
10. Голос Бога
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Восход. Солнцев. Книга X

Мастер 7

Чащин Валерий
7. Мастер
Фантастика:
фэнтези
боевая фантастика
попаданцы
технофэнтези
аниме
5.00
рейтинг книги
Мастер 7

Неудержимый. Книга XIV

Боярский Андрей
14. Неудержимый
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Неудержимый. Книга XIV

Все не случайно

Юнина Наталья
Любовные романы:
современные любовные романы
7.10
рейтинг книги
Все не случайно

Гром над Тверью

Машуков Тимур
1. Гром над миром
Фантастика:
боевая фантастика
5.89
рейтинг книги
Гром над Тверью

Идущий в тени 5

Амврелий Марк
5. Идущий в тени
Фантастика:
фэнтези
рпг
5.50
рейтинг книги
Идущий в тени 5

Кровь, золото и помидоры

Распопов Дмитрий Викторович
4. Венецианский купец
Фантастика:
альтернативная история
5.40
рейтинг книги
Кровь, золото и помидоры

Неудержимый. Книга VIII

Боярский Андрей
8. Неудержимый
Фантастика:
фэнтези
попаданцы
аниме
6.00
рейтинг книги
Неудержимый. Книга VIII

Чужое наследие

Кораблев Родион
3. Другая сторона
Фантастика:
боевая фантастика
8.47
рейтинг книги
Чужое наследие

Пистоль и шпага

Дроздов Анатолий Федорович
2. Штуцер и тесак
Фантастика:
альтернативная история
8.28
рейтинг книги
Пистоль и шпага

Мастер 4

Чащин Валерий
4. Мастер
Фантастика:
героическая фантастика
боевая фантастика
попаданцы
5.00
рейтинг книги
Мастер 4

Темный Патриарх Светлого Рода 6

Лисицин Евгений
6. Темный Патриарх Светлого Рода
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Темный Патриарх Светлого Рода 6

Лорд Системы 14

Токсик Саша
14. Лорд Системы
Фантастика:
фэнтези
попаданцы
рпг
5.00
рейтинг книги
Лорд Системы 14

Падение Твердыни

Распопов Дмитрий Викторович
6. Венецианский купец
Фантастика:
попаданцы
альтернативная история
5.33
рейтинг книги
Падение Твердыни