UNIX: разработка сетевых приложений
UNIX: разработка сетевых приложений читать книгу онлайн
Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
4 main(int argc, char **argv) 5 { 6 int sockfd, family, port; 7 const int on = 1; 8 pid_t pid; 9 socklen_t salen;10 struct sockaddr *sa, *wild;11 struct ifi_info *ifi, *ifihead;12 if (argc == 2)13 sockfd = Udp_client(NULL, argv[1], (void**)&sa, &salen);14 else if (argc == 3)15 sockfd = Udp_client(argv[1], argv[2], (void**)&sa, &salen);16 else17 err_quit("usage; udpserv04 [ <host> ] <service or port>");18 family = sa->sa_family;19 port = sock_get_port(sa, salen);20 Close(sockfd); /* хотим узнать семейство, порт salen */21 for (ifihead = ifi = Get_ifi_info(family, 1),22 ifi ! = NULL; ifi = ifi->ifi_next) {23 /* связывание с многоадресными адресами */24 sockfd = Socket(family, SOCK_DGRAM, 0);25 Setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));26 sock_set_port(ifi->ifi_addr, salen, port);27 Bind(sockfd, ifi->ifi_addr, salen);28 printf("bound %sn", Sock_ntop(ifi->ifi_addr, salen));29 if ((pid = Fork()) == 0) { /* дочерний процесс */30 mydg_echo(sockfd, ifi->ifi_addr, salen);31 exit(0); /* никогда не выполняется */32 }33 if (ifi->ifi_flags & IFF_BROADCAST) {34 /* попытка связывания с широковещательным адресом */35 sockfd = Socket(family, SOCK_DGRAM, 0);36 Setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));37 sock_set_port(ifi->ifi_brdaddr, salen, port);38 if (bind(sockfd, ifi->ifi_brdaddr, salen) < 0) {39 if (errno == EADDRINUSE) {40 printf("EADDRINUSE: %sn",41 Sock_ntop(ifi->ifi_brdaddr, salen));42 Close(sockfd);43 continue;44 } else45 err_sys("bind error for %s",46 Sock_ntop(ifi->ifi_brdaddr, salen));47 }48 printf ("bound %sn", Sock_ntop(ifi->ifi_brdaddr, salen));49 if ((pid = Fork()) == 0) { /* дочерний процесс */50 mydg_echo(sockfd, ifi->ifi_brdaddr, salen);51 exit(0); /* никогда не выполняется */52 }53 }54 }55 /* связывание с универсальным адресом */56 sockfd = Socket(family, SOCK_DGRAM, 0);57 Setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));58 wild = Malloc(salen);59 memcpy(wild, sa, salen); /* копирует семейство и порт */60 sock_set_wild(wild, salen);61 Bind(sockfd, wild, salen);62 printf("bound %sn", Sock_ntop(wild, salen));63 if ((pid = Fork()) == 0) { /* дочерний процесс */64 mydg_echo(sockfd, wild, salen);65 exit(0); /* никогда не выполняется */66 }67 exit(0);68 }69 void70 mydg_echo(int sockfd, SA *myaddr, socklen_t salen)71 {72 int n;73 char mesg[MAXLINE];74 socklen_t len;75 struct sockaddr *cli;76 cli = Malloc(salen);77 for (;;) {78 len = salen;79 n = Recvfrom(sockfd, mesg, MAXLINE, 0, cli, &len);80 printf("child %d, datagram from %s",81 getpid(), Sock_ntop(cli, len));82 printf(", to %sn", Sock_ntop(myaddr, salen));83 Sendto(sockfd, mesg, n, 0, cli, len),84 }85 }Глава 24
24.1. Да, разница есть. В первом примере два байта отсылаются с единственным срочным указателем, который указывает на байт, следующий за
bab
