UNIX: разработка сетевых приложений - Страница 393
35 void36 do_parent(void)27 {38 int backlog, j, k, junk, fd[MAXBACKLOG + 1];39 Close(cfd);40 Signal(SIGALRM, parent_alrm);41 for (backlog = 0; backlog <= 14; backlogs) {42 printf("backlog = %d. ", backlog);43 Write(pfd, &backlog. sizeof(int)); /* сообщение значения дочернему процессу */44 Read(pfd, &junk, sizeof(int)); /* ожидание дочернего процесса */45 for (j = 1; j <= MAXBACKLOG; j++) {46 fd[j] = Socket(AF_INET, SOCK_STREAM, 0);47 alarm(2);48 if (connect(fd[j], (SA*)&serv, sizeof(serv)) < 0) {49 if (errno != EINTR)50 err_sys("connect error, j = %d", j);51 printf("timeout, %d connections completedn", j - 1);52 for (k = 1; k <= j; k++)53 Close(fd[k]);54 break; /* следующее значение backlog */55 }56 alarm(0);57 }58 if (j > MAXBACKLOG)59 printf("Id connections?n", MAXBACKLOG);60 }61 backlog = -1; /* сообщаем дочернему процессу, что все сделано */62 Write(pfd, &backlog, sizeof(int));63 }64 void65 do_child(void)66 {67 int listenfd, backlog, junk;68 const int on = 1;69 Close(pfd);70 Read(cfd, &backlog, sizeof(int)); /* ожидание родительского процесса */71 while (backlog >= 0) {72 listenfd = Socket(AF_NET, SOCK_STREAM, 0);73 Setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));74 Bind(listenfd, (SA*)&serv, sizeof(serv));75 Listen(listenfd, backlog); /* начало прослушивания */76 Write(cfd, &junk, sizeof(int)); /* сообщение родительскому процессу */77 Read(cfd, &backlog, sizeof(int)); /* ожидание родительского процесса */78 Close(listenfd); /* также закрывает все соединения в очереди */79 }80 }Глава 16
16.1. Дескриптор используется совместно родительским и дочерним процессами, поэтому его счетчик ссылок равен 2. Если родительский процесс вызывает функцию
closeshutdown16.2. Родительский процесс продолжит запись в сокет, получивший сегмент FIN, а первый сегмент, посланный серверу, вызовет получение сегмента RST в ответ. После этого функция
writeSIGPIPE16.3. Когда дочерний процесс вызывает функцию
getppidSIGTERMinitinitinitgetppid16.4. Если удалить эти две строки, вызывается функция
selectselectgotoselect16.5. Это может случиться, если сервер отправляет данные сразу, как только завершается его функция
acceptГлава 17
17.1. Нет, это не имеет значения, поскольку первые три элемента объединения в листинге 17.1 являются структурами адреса сокета.
Глава 18
18.1. Элемент
sdl_nlensdl_alen18.2. На этот сокет никогда не посылается ответ от ядра. Данный параметр сокета (
SO_USELOOPBACKГлава 20
20.1. Если вы получаете большое количество ответов, они могут следовать каждый раз в разном порядке. Правда, отправляющий узел обычно выводится первым, поскольку дейтаграммы, направленные к нему или от него, не появляются в реальной сети.