UNIX: разработка сетевых приложений
UNIX: разработка сетевых приложений читать книгу онлайн
Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
Мы работаем с двумя буферами: буфер to содержит данные, направляющиеся из стандартного потока ввода к серверу, а буфер
frto
Рис. 16.1. Буфер, содержащий данные из стандартного потока ввода, идущие к сокету
Указатель
toiptrtooptr&to[MAXLINE]toiptrtooptrtoiptrНа рис. 16.2 показана соответствующая организация буфера
fr
Рис. 16.2. Буфер, содержащий данные из сокета, идущие к стандартному устройству вывода
Листинг 16.1. Функция str_cli: первая часть, инициализация и вызов функции
//nonblock/strclinonb.c 1 #include "unp.h" 2 void 3 str_cli(FILE *fp, int sockfd) 4 { 5 int maxfdp1, val, stdineof; 6 ssize_t n, nwritten; 7 fd_set rset, wset; 8 char to[MAXLINE], fr[MAXLINE]; 9 char *toiptr, *tooptr, *friptr, *froptr;10 val = Fcntl(sockfd, F_GETFL, 0);11 Fcntl(sockfd, F_SETFL, val | O_NONBLOCK);12 val = Fcntl(STDIN_FILENO, F_SETFL, 0);13 Fcntl(STDIN_FILENO, F_SETFL, val | O_NONBLOCK);14 val = Fcntl(STDOUT_FILENO, F_SETFL, 0);15 Fcntl(STDOUT_FILENO, F_SETFL, val | O_NONBLOCK);16 toiptr = tooptr = to; /* инициализация указателей буфера */17 friptr = froptr = fr;18 stdineof = 0;19 maxfdp1 = max(max(STDIN_FILENO, STDOUT_FILENO), sockfd) + 1;20 for (;;) {21 FD_ZERO(&rset);22 FD_ZERO(&wset);23 if (stdineof == 0 && toiptr < &to[MAXLINE])24 FD_SET(STDIN_FILENO, &rset); /* чтение из стандартного потока ввода */25 if (friptr < &fr[MAXLINE])26 FD_SET(sockfd, &rset); /* чтение из сокета */27 if (tooptr != toiptr)28 FD_SET(sockfd, &wset); /* данные для записи в сокет */29 if (froptr != friptr)30 FD_SET(STDOUT_FILENO, &wset); /* данные для записи в стандартный поток вывода */31 Select(maxfdp1, &rset, &wset, NULL, NULL);10-15fcntl16-19select20select21-30tofrtofr31selectСледующая часть нашей функции показана в листинге 16.2. Этот код содержит первые две проверки (из четырех возможных), выполняемые после завершения функции
selectЛистинг 16.2. Функция str_cli: вторая часть, чтение из стандартного потока ввода или сокета
//nonblock/strclinonb.c32 if (FD_ISSET(STDIN_FILENO, &rset)) {33 if ((n = read(STDIN_FILENO, toiptr, &to[MAXLINE] - toiptr)) < 0) {34 if (errno != EWOULDBLOCK)35 err_sys("read error on stdin");36 } else if (n == 0) {
