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

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

Жанры

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

11 recvline[n] = 0; /* завершающий нуль */

12 Fputs(recvline, stdout);

13 }

14 }

Изменения по сравнению с предыдущей версией — это добавление вызова функции

connect
и замена вызовов функций
sendto
и recvfrom вызовами функций
write
и
read
. Функция
dg_cli
остается не зависящей от протокола, поскольку она не вникает в структуру адреса сокета, передаваемую функции
connect
.
Наша функция
main
клиента, показанная в листинге 8.3, остается той же.

Если мы запустим программу на узле

macosx
, задав IP-адрес узла
freebsd4
(который не запускает наш сервер на порте 9877), мы получим следующий вывод:

macosx % udpcli04 172.24.37.94

hello, world

read error: Connection refused

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

connect
, задавая узел сервера, на котором не запущен процесс сервера, функция
connect
возвращает ошибку, поскольку вызов функции
connect
вызывает отправку первого пакета трехэтапного рукопожатия TCP, и именно этот пакет вызывает получение сегмента RST от собеседника (см. раздел 4.3).

В листинге 8.8 показан вывод программы

tcpdump
.

Листинг 8.8. Вывод программы tcpdump при запуске функции dg_cli

macosx % tcpdump

01 0.0 macosx.51139 > freebsd4 9877:udp 13

02 0.006180 ( 0.0062) freebsd4 > macosx: icmp: freebsd4 udp port 9877 unreachable

В табл. A.5 мы также видим, что возникшую ошибку ICMP ядро сопоставляет ошибке

ECONNREFUSED
, которая соответствует выводу строки сообщения
Connection refused
(В соединении отказано) функцией
err_sys
.

ПРИМЕЧАНИЕ

К сожалению, не все ядра возвращают сообщения ICMP присоединенному сокету UDP, как мы показали в этом разделе. Обычно ядра реализаций, происходящих от Беркли, возвращают эту ошибку, а ядра System V — не возвращают. Например, если мы запустим тот же клиент на узле Solaris 2.4 и с помощью функции connect соединимся с узлом, на котором не запущен наш сервер, то с помощью программы tcpdump мы сможем убедиться, что ошибка ICMP о недоступности порта возвращается узлом сервера, но вызванная клиентом функция read никогда не завершается. Эта ситуация была исправлена в Solaris 2.5. UnixWare не возвращает ошибку, в то время как AIX, Digital Unix, HP-UX и Linux возвращают.

8.13. Отсутствие управления потоком в UDP

Теперь мы проверим, как влияет на работу приложения отсутствие какого-либо управления потоком в UDP. Сначала мы изменим нашу функцию

dg_cli
так, чтобы она отправляла фиксированное число дейтаграмм. Она больше не будет читать из стандартного потока ввода. В листинге 8.9 показана новая версия функции. Эта функция отправляет серверу 2000 дейтаграмм UDP по 1400 байт каждая.

Листинг 8.9. Функция dg_cli, отсылающая

фиксированное число дейтаграмм серверу

//udpcliserv/dgcliloop1.c

1 #include "unp.h"

2 #define NDG 2000 /* количество дейтаграмм для отправки */

3 #define DGLEN 1400 /* длина каждой дейтаграммы */

4 void

5 dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)

6 {

7 int i;

8 char sendline[DGLEN];

9 for (i = 0; i < NDG; i++) {

10 Sendto(sockfd, sendline, DGLEN, 0, pservaddr, servlen);

11 }

12 }

Затем мы изменяем сервер так, чтобы он получал дейтаграммы и считал число полученных дейтаграмм. Сервер больше не отражает дейтаграммы обратно клиенту. В листинге 8.10 показана новая функция

dg_echo
. Когда мы завершаем процесс сервера нажатием клавиши прерывания на терминале (что приводит к отправке сигнала
SIGINT
процессу), сервер выводит число полученных дейтаграмм и завершается.

Листинг 8.10. Функция dg_echo, считающая полученные дейтаграммы

//udpcliserv/dgecholoop1.c

1 #include "unp.h"

2 static void recvfrom_int(int);

3 static int count;

4 void

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

6 {

7 socklen_t len;

8 char mesg[MAXLINE];

9 Signal (SIGINT, recvfrom_int);

10 for (;;) {

11 len = clilen;

12 Recvfrom(sockfd, mesg, MAXLINE, 0, pcliaddr, &len);

13 count++;

14 }

15 }

16 static void

17 recvfrom_int(int signo)

18 {

19 printf("\nreceived %d datagrams\n", count);

20 exit(0);

21 }

Теперь мы запускаем сервер на узле

freebsd
, который представляет собой медленный компьютер SPARCStation. Клиент мы запускаем в значительно более быстрой системе RS/6000 с операционной системой
aix
. Они соединены друг с другом напрямую каналом Ethernet на 100 Мбит/с. Кроме того, мы запускаем программу
netstat -s
на узле сервера и до, и после запуска клиента и сервера, поскольку выводимая статистика покажет, сколько дейтаграмм мы потеряли. В листинге 8.11 показан вывод сервера.

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

На границе империй. Том 4

INDIGO
4. Фортуна дама переменчивая
Фантастика:
космическая фантастика
6.00
рейтинг книги
На границе империй. Том 4

Царь Федор. Трилогия

Злотников Роман Валерьевич
Царь Федор
Фантастика:
альтернативная история
8.68
рейтинг книги
Царь Федор. Трилогия

Неожиданный наследник

Яманов Александр
1. Царь Иоанн Кровавый
Приключения:
исторические приключения
5.00
рейтинг книги
Неожиданный наследник

Земная жена на экспорт

Шах Ольга
Любовные романы:
любовно-фантастические романы
5.57
рейтинг книги
Земная жена на экспорт

Разбуди меня

Рам Янка
7. Серьёзные мальчики в форме
Любовные романы:
современные любовные романы
остросюжетные любовные романы
5.00
рейтинг книги
Разбуди меня

Пустоши

Сай Ярослав
1. Медорфенов
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Пустоши

Возвышение Меркурия. Книга 4

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

Я не Монте-Кристо

Тоцка Тала
Любовные романы:
современные любовные романы
5.57
рейтинг книги
Я не Монте-Кристо

Дурная жена неверного дракона

Ганова Алиса
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Дурная жена неверного дракона

Наследник в Зеркальной Маске

Тарс Элиан
8. Десять Принцев Российской Империи
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Наследник в Зеркальной Маске

Хроники Сиалы. Трилогия

Пехов Алексей Юрьевич
Хроники Сиалы
Фантастика:
фэнтези
9.03
рейтинг книги
Хроники Сиалы. Трилогия

Жена по ошибке

Ардова Алиса
Любовные романы:
любовно-фантастические романы
7.71
рейтинг книги
Жена по ошибке

Аватар

Жгулёв Пётр Николаевич
6. Real-Rpg
Фантастика:
боевая фантастика
5.33
рейтинг книги
Аватар

Ваше Сиятельство 6

Моури Эрли
6. Ваше Сиятельство
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Ваше Сиятельство 6