UNIX: разработка сетевых приложений
UNIX: разработка сетевых приложений читать книгу онлайн
Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
В листинге 6.3 показана первая половина этой версии сервера.
Листинг 6.3. Сервер TCP, использующий одиночный процесс и функцию select: инициализация
//tcpcliserv/tcpservselect01.c 1 #include "unp.h" 2 int 3 main(int argc, char **argv) 4 { 5 int i, maxi, maxfd, listenfd, connfd, sockfd; 6 int nready, client[FD_SETSIZE], 7 ssize_t n; 8 fd_set rset, allset; 9 char buf[MAXLINE];10 socklen_t clilen;11 struct sockaddr_in cliaddr, servaddr;12 listenfd = Socket(AF_INET, SOCK_STREAM, 0);13 bzero(&servaddr, sizeof(servaddr));14 servaddr.sin_family = AF_INET;15 servaddr.sin_addr.s_addr = htonl(INADDR_ANY);16 servaddr.sin_port = htons(SERV_PORT);17 Bind(listenfd, (SA*)&servaddr, sizeof(servaddr));18 Listen(listenfd, LISTENQ);19 maxfd = listenfd; /* инициализация */20 maxi = -1; /* индекс в массиве client[] */21 for (i = 0; i < FD_SETSIZE; i++)22 client[i] = -1; /* -1 означает свободный элемент */23 FD_ZERO(&allset);24 FD_SET(listenfd, &allset);12-24socketbindlistenselectВторая половина функции
mainЛистинг 6.4. Сервер TCP, использующей одиночный процесс и функцию select: цикл
//tcpcliserv/tcpservselect01.c25 for (;;) {26 rset = allset; /* присваивание значения структуре */27 nready = Select(maxfd + 1, &rset, NULL, NULL, NULL);28 if (FD_ISSET(listenfd, &rset)) { /* соединение с новым клиентом */29 clilen = sizeof(cliaddr);30 connfd = Accept(listenfd, (SA*)&cliaddr, &clilen);31 for (i = 0; i < FD_SETSIZE; i++)32 if (client[i] < 0) {33 client[i] = connfd; /* сохраняем дескриптор */34 break;35 }36 if (i == FD_SETSIZE)37 err_quit("too many clients");38 FD_SET(connfd, &allset); /* добавление нового дескриптора */39 if (connfd > maxfd)40 maxfd = connfd; /* для функции select */41 if (i > maxi)42 maxi = i; /* максимальный индекс в массиве clientf[] */43 if (--nready <= 0)44 continue; /* больше нет дескрипторов, готовых для чтения */45 }46 for (i = 0; i <= maxi; i++) { /* проверяем все клиенты на наличие данных */47 if ((sockfd - client[i]) < 0)48 continue;49 if (FD_ISSET(sockfd, &rset)) {50 if ((n = Read(sockfd, buf, MAXLINE)) == 0) {51 /* соединение закрыто клиентом */52 Close(sockfd);53 FD_CLR(sockfd, &allset);54 client[i] = -1;55 } else56 Writen(sockfd, line, n);57 if (--nready <= 0)58 break; /* больше нет дескрипторов, готовых для чтения */59 }60 }61 }62 }26-27select28-45acceptclientforselect46-60select
