UNIX: разработка сетевых приложений
UNIX: разработка сетевых приложений читать книгу онлайн
Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
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 не составляет труда переполнить буфер получателя.
Если мы посмотрим на вывод программы
netstatdropped due to full socket buffersnetstatЧисло дейтаграмм, полученных сервером в этом примере, недетерминировано. Оно зависит от многих факторов, таких как нагрузка сети, загруженность узла клиента и узла сервера.
Если мы запустим тот же клиент и тот же сервер, но на этот раз клиент на медленной системе Sun, а сервер на быстрой системе RS/6000, никакие дейтаграммы не теряются.
aix % <b>udpserv06</b><b>^?</b> <i>после окончания работы клиента вводим наш символ прерывания</i>received 2000 datagramsПриемный буфер сокета UDP
Число дейтаграмм UDP, установленных в очередь UDP, для данного сокета ограничено размером его приемного буфера. Мы можем изменить его с помощью параметра сокета
SO_RCVBUFdg_echoЛистинг 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 void20 recvfrom_int(int signo)21 {22 printf("nreceived %d datagramsn", 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 байт.
8.14. Определение исходящего интерфейса для UDP
С помощью присоединенного сокета UDP можно также задавать исходящий интерфейс, который будет использован для отправки дейтаграмм к определенному получателю. Это объясняется побочным эффектом функции
connectbindВ листинге 8.13 показана простая программа UDP, которая с помощью функции connect соединяется с заданным IP-адресом и затем вызывает функцию
getsocknameЛистинг 8.13. Программа UDP, использующая функцию connect для определения исходящего интерфейса
//udpcliserv/udpcli09.c 1 #include "unp.h" 2 int 3 main(int argc, char **argv) 4 { 5 int sockfd; 6 socklen_t len; 7 struct sockaddr_in cliaddr, servaddr; 8 if (argc != 2)
