Уильям Стивенс - UNIX: разработка сетевых приложений

Тут можно читать онлайн Уильям Стивенс - UNIX: разработка сетевых приложений - бесплатно ознакомительный отрывок. Жанр: comp-osnet, издательство Питер, год 2007. Здесь Вы можете читать ознакомительный отрывок из книги онлайн без регистрации и SMS на сайте лучшей интернет библиотеки ЛибКинг или прочесть краткое содержание (суть), предисловие и аннотацию. Так же сможете купить и скачать торрент в электронном формате fb2, найти и слушать аудиокнигу на русском языке или узнать сколько частей в серии и всего страниц в публикации. Читателям доступно смотреть обложку, картинки, описание и отзывы (комментарии) о произведении.
  • Название:
    UNIX: разработка сетевых приложений
  • Автор:
  • Жанр:
  • Издательство:
    Питер
  • Год:
    2007
  • Город:
    Санкт-Петербург
  • ISBN:
    5-94723-991-4
  • Рейтинг:
    4.33/5. Голосов: 91
  • Избранное:
    Добавить в избранное
  • Отзывы:
  • Ваша оценка:
    • 80
    • 1
    • 2
    • 3
    • 4
    • 5

Уильям Стивенс - UNIX: разработка сетевых приложений краткое содержание

UNIX: разработка сетевых приложений - описание и краткое содержание, автор Уильям Стивенс, читайте бесплатно онлайн на сайте электронной библиотеки LibKing.Ru

Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.

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

UNIX: разработка сетевых приложений - читать книгу онлайн бесплатно (ознакомительный отрывок), автор Уильям Стивенс
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

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 показан вывод сервера.

Листинг 8.11. Вывод на узле сервера

freebsd % netstat -s -p udp

udp:

71208 datagrams received

0 with incomplete header

0 with bad data length field

0 with bad checksum

0 with no checksum

832 dropped due to no socket

16 broadcast/multicast datagrams dropped due to no socket

1971 dropped due to full socket buffers

0 not for hashed pcb

68389 delivered

137685 datagrams output

freebsd % udpserv06 запускаем наш сервер

клиент посылает дейтаграммы

^C для окончания работы клиента вводим наш символ прерывания

freebsd % netstat -s -р udp

udp

73208 datagrams received

0 with incomplete header

0 with bad data length field

0 with bad checksum

0 with no checksum

832 dropped due to no socket

16 broadcast/multicast datagrams dropped due to no socket

3941 dropped due to full socket buffers

0 not for hashed pcb

68419 delivered

137685 datagrams output

Клиент отправил 2000 дейтаграмм, но приложение-сервер получило только 30 из них, что означает уровень потерь 98%. Ни сервер, ни клиент не получают сообщения о том, что эти дейтаграммы потеряны. Как мы и говорили, UDP не имеет возможности управления потоком — он ненадежен. Как мы показали, для отправителя UDP не составляет труда переполнить буфер получателя.

Если мы посмотрим на вывод программы netstat, то увидим, что общее число дейтаграмм, полученных узлом сервера (не приложением-сервером) равно 2000 (73 208 – 71 208). Счетчик dropped due to full socket buffers(отброшено из-за переполнения буферов сокета) показывает, сколько дейтаграмм было получено UDP и проигнорировано из-за того, что приемный буфер принимающего сокета был полон [128, с. 775]. Это значение равно 1970 (3941 – 1971), что при добавлении к выводу счетчика дейтаграмм, полученных приложением (30), дает 2000 дейтаграмм, полученных узлом. К сожалению, счетчик дейтаграмм, отброшенных из-за заполненного буфера, в программе netstatраспространяется на всю систему. Не существует способа определить, на какие приложения (например, какие порты UDP) это влияет.

Число дейтаграмм, полученных сервером в этом примере, недетерминировано. Оно зависит от многих факторов, таких как нагрузка сети, загруженность узла клиента и узла сервера.

Если мы запустим тот же клиент и тот же сервер, но на этот раз клиент на медленной системе Sun, а сервер на быстрой системе RS/6000, никакие дейтаграммы не теряются.

aix % udpserv06

^? после окончания работы клиента вводим наш символ прерывания

received 2000 datagrams

Приемный буфер сокета UDP

Число дейтаграмм UDP, установленных в очередь UDP, для данного сокета ограничено размером его приемного буфера. Мы можем изменить его с помощью параметра сокета SO_RCVBUF, как мы показали в разделе 7.5. В FreeBSD по умолчанию размер приемного буфера сокета UDP равен 42 080 байт, что допускает возможность хранения только 30 из наших 1400-байтовых дейтаграмм. Если мы увеличим размер приемного буфера сокета, то можем рассчитывать, что сервер получит дополнительные дейтаграммы. В листинге 8.12 представлена измененная функция dg_echoиз листинга 8.10, которая увеличивает размер приемного буфера сокета до 240 Кбайт. Если мы запустим этот сервер в системе Sun, а клиент — в системе RS/6000, то счетчик полученных дейтаграмм будет иметь значение 103. Поскольку это лишь немногим лучше, чем в предыдущем примере с размером буфера, заданным по умолчанию, ясно, что мы пока не получили решения проблемы.

Листинг 8.12. Функция dg_echo, увеличивающая размер приемного буфера сокета

//udpcliserv/dgecholоор2.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 int n;

8 socklen_t len;

9 char mesg[MAXLINE];

10 Signal(SIGINT, recvfrom_int);

11 n = 240 * 1024;

12 Setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &n, sizeof(n));

13 for (;;) {

14 len = clilen;

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

16 count++;

17 }

18 }

19 static void

20 recvfrom_int(int signo)

21 {

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

23 exit(0);

24 }

ПРИМЕЧАНИЕ

Почему мы устанавливаем размер буфера приема сокета равным 240×1024 байт в листинге 8.12? Максимальный размер приемного буфера сокета в BSD/OS 2.1 по умолчанию равен 262 144 байта (256×1024), но из-за способа размещения буфера в памяти (описанного в главе 2 [128]) он в действительности ограничен до 246 723 байт. Многие более ранние системы, основанные на 4.3BSD, ограничивали размер буфера приема сокета примерно до 52 000 байт.

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать


Уильям Стивенс читать все книги автора по порядку

Уильям Стивенс - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки LibKing.




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


Отзывы читателей о книге UNIX: разработка сетевых приложений, автор: Уильям Стивенс. Читайте комментарии и мнения людей о произведении.


Понравилась книга? Поделитесь впечатлениями - оставьте Ваш отзыв или расскажите друзьям

Напишите свой комментарий
x