UNIX: разработка сетевых приложений
UNIX: разработка сетевых приложений читать книгу онлайн
Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
В листинге 8.8 показан вывод программы
tcpdumpЛистинг 8.8. Вывод программы tcpdump при запуске функции dg_cli
macosx % <b>tcpdump</b>01 0.0 macosx.51139 > freebsd4 9877:udp 1302 0.006180 ( 0.0062) freebsd4 > macosx: icmp: freebsd4 udp port 9877 unreachableВ табл. A.5 мы также видим, что возникшую ошибку ICMP ядро сопоставляет ошибке
ECONNREFUSEDConnection refusederr_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. Функция 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_echoSIGINTЛистинг 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 void17 recvfrom_int(int signo)18 {19 printf("nreceived %d datagramsn", count);20 exit(0);21 }Теперь мы запускаем сервер на узле
freebsdaixnetstat -sЛистинг 8.11. Вывод на узле сервера
freebsd % <b>netstat -s -p udp</b>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 outputfreebsd % <b>udpserv06</b> <i>запускаем наш сервер</i><i> клиент посылает дейтаграммы</i><b>^C </b><i>для окончания работы клиента вводим наш символ прерывания</i>freebsd % <b>netstat -s -р udp</b>udp 73208 datagrams received 0 with incomplete header 0 with bad data length field
