UNIX: разработка сетевых приложений
UNIX: разработка сетевых приложений читать книгу онлайн
Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
■ В Беркли-реализациях (а также POSIX) имеются два следующих правила, относящихся к функции
selectconnectЭти два правила в отношении функции select выпадают из общего ряда наших правил из раздела 6.3 относительно условий, при которых дескриптор становится готовым для чтения или записи. В сокет TCP можно записывать, если достаточно места в буфере отправки (что всегда будет выполнено в случае присоединенного сокета, поскольку мы еще ничего не записали в сокет) и сокет является присоединенным (что выполняется, только когда завершено трехэтапное рукопожатие). При наличии ошибки, ожидающей обработки, появляется возможность читать из сокета и записывать в сокет.
С неблокируемыми функциями
connect16.4. Неблокируемая функция connect: клиент времени и даты
В листинге 16.7 показана наша функция
connect_nonbconnectconnectif (connect_nonb(sockfd, (SA*)&servaddr, sizeof(servaddr), 0) < 0)err_sys("connect error");Первые три аргумента являются обычными аргументами функции
connectselectЛистинг 16.7. Неблокируемая функция connect
//lib/connect_nonb.c 1 #include "unp.h" 2 int 3 connect_nonb(int sockfd, const SA *saptr, socklen_t salen, int nsec) 4 { 5 int flags, n, error; 6 socklen_t len; 7 fd_set rset, wset; 8 struct timeval tval; 9 flags = Fcntl(sockfd, F_GETFL, 0);10 Fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);11 error = 0;12 if ((n = connect(sockfd, saptr, salen)) < 0)13 if (errno != EINPROGRESS)14 return (-1);15 /* Пока соединение устанавливается, мы можем заняться чем-то другим */16 if (n == 0)17 goto done; /* функция connect завершилась немедленно */18 FD_ZERO(&rset);19 FDSET(sockfd, &rset);20 wset = rset;21 tval.tv_sec = nsec;22 tval.tv_usec = 0;23 if ((n = Select(sockfd + 1, &rset, &wset, NULL,24 nsec ? &tval : NULL)) == 0) {25 close(sockfd); /* тайм-аут */26 errno = ETIMEDOUT;27 return (-1);28 }29 if (FD_ISSET(sockfd, &rset) || FD_ISSET(sockfd, &wset)) {30 len = sizeof(error);31 if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len) < 0)32 return (-1); /*в Solaris ошибка, ожидающая обработки */33 } else34 err_quit("select error: sockfd not set");35 done:36 Fcntl(sockfd, F_SETFL, flags); /* восстанавливаем флаги, задающие статус файла */37 if (error) {38 close(sockfd); /* на всякий случай */39 errno = error;40 return (-1);41 }42 return (0);43 }9-10fcntl11-14connectEINPROGRESS1516-17connect18-24selectrsetsockfdrsetwsettimevalselectselecttimeval
