UNIX: разработка сетевых приложений
UNIX: разработка сетевых приложений читать книгу онлайн
Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
9 err_quit("usage: udpcli <Ipaddress>");10 sockfd = Socket(AF_INET, SOCK_DGRAM, 0);11 bzero(&servaddr, sizeof(servaddr));12 servaddr.sin_family = AF_INET;13 servaddr.sin_port = htons(SERV_PORT);14 Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);15 Connect(sockfd, (SA*)&servaddr, sizeof(servaddr));16 len = sizeof(cliaddr);17 Getsockname(sockfd, (SA*)&cliaddr, &len);18 printf("local address %sn", Sock_ntop((SA*)&cliaddr, len));19 exit(0);20 }Если мы запустим программу на узле
freebsdfreebsd % <b>udpcli09 206.168.112.96</b>local address 12.106.32.254:52329freebsd % <b>udpcli09 192.168.42.2</b>local address 192.168.42.1:52330freebsd % <b>udpcli09 127.0.0.1</b>local address 127.0.0.1:52331По рис. 1.7 видно, что когда мы запускаем программу первые два раза, аргументом командной строки является IP-адрес в разных сетях Ethernet. Ядро присваивает локальный IP-адрес первичному адресу интерфейса в соответствующей сети Ethernet. При вызове функции
connectК сожалению, эта технология действует не во всех реализациях, что особенно касается ядер, происходящих от SVR4. Например, это не работает в Solaris 2.5, но работает в AIX, Digital Unix, Linux, MacOS X и Solaris 2.6.
8.15. Эхо-сервер TCP и UDP, использующий функцию select
Теперь мы объединим наш параллельный эхо-сервер TCP из главы 5 и наш последовательный эхо-сервер UDP из данной главы в один сервер, использующий функцию
selectЛистинг 8.14. Первая часть эхо-сервера, обрабатывающего сокеты TCP и UDP при помощи функции select
//udpcliserv/udpservselect01.c 1 #include "unp.h" 2 int 3 main(int argc, char **argv) 4 { 5 int listenfd, connfd, udpfd, nready, maxfdp1; 6 char mesg[MAXLINE]; 7 pid_t childpid; 8 fd_set rset; 9 ssize_t n;10 socklen_t len;11 const int on = 1;12 struct sockaddr_in cliaddr, servaddr;13 void sig_chld(int);14 /* создание прослушиваемого сокета TCP */15 listenfd = Socket(AF_INET, SOCK_STREAM, 0);16 bzero(&servaddr, sizeof(servaddr));17 servaddr.sin_family = AF_INET;18 servaddr.sin_addr.s_addr = htonl(INADDR_ANY);19 servaddr.sin_port = htons(SERV_PORT);20 Setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));21 Bind(listenfd, (SA*)&servaddr, sizeof(servaddr));22 Listen(listenfd, LISTENQ);23 /* создание сокета UDP */24 udpfd = Socket(AF_INET, SOCK_DGRAM, 0);25 bzero(&servaddr, sizeof(servaddr));26 servaddr.sin_family = AF_INET;27 servaddr.sin_addr.s_addr = htonl(INADDR_ANY);28 servaddr.sin_port = htons(SERV_PORT);29 Bind(udpfd, (SA*)&servaddr, sizeof(servaddr));14-22SO_REUSEADDR23-29SO_REUSEADDRbindВ листинге 8.15 показана вторая часть нашего сервера.
Листинг 8.15. Вторая половина эхо-сервера, обрабатывающего TCP и UDP при помощи функции select
udpcliserv/udpservselect01.c30 Signal(SIGCHLD, sig_chld); /* требуется вызвать waitpid() */31 FD_ZERO(&rset);32 maxfdp1 = max(listenfd, udpfd) + 1;33 for (;;) {34 FD_SET(listenfd, &rset);35 FD_SET(udpfd, &rset);36 if ((nready = select(maxfdp1, &rset, NULL, NULL, NULL)) < 0) {37 if (errno == EINTR)
