UNIX: разработка сетевых приложений

На нашем литературном портале можно бесплатно читать книгу UNIX: разработка сетевых приложений, Стивенс Уильям Ричард-- . Жанр: ОС и Сети. Онлайн библиотека дает возможность прочитать весь текст и даже без регистрации и СМС подтверждения на нашем литературном портале bazaknig.info.
UNIX: разработка сетевых приложений
Название: UNIX: разработка сетевых приложений
Дата добавления: 16 январь 2020
Количество просмотров: 760
Читать онлайн

UNIX: разработка сетевых приложений читать книгу онлайн

UNIX: разработка сетевых приложений - читать бесплатно онлайн , автор Стивенс Уильям Ричард

Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.

Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала

Перейти на страницу:

35 void

36 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 void

65 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. Если родительский процесс вызывает функцию

close
, счетчик ссылок уменьшается с 2 до 1, и пока он больше нуля, сегмент FIN не посылается. Еще одна цель вызова функции
shutdown
— послать сегмент FIN, даже если дескриптор больше нуля.

16.2. Родительский процесс продолжит запись в сокет, получивший сегмент FIN, а первый сегмент, посланный серверу, вызовет получение сегмента RST в ответ. После этого функция

write
пошлет родительскому процессу сигнал
SIGPIPE
, как показано в разделе 5.12.

16.3. Когда дочерний процесс вызывает функцию

getppid
для отправки сигнала
SIGTERM
, возвращаемый идентификатор процесса будет равен 1. Это указывает на процесс
init
, наследующий все продолжающие работать дочерние процессы, родительские процессы которых завершились. Дочерний процесс будет пытаться послать сигнал процессу
init
, не имея необходимых прав доступа. Но если не исключается, что данный клиент будет запущен с правами привилегированного пользователя, позволяющими посылать сигналы процессу
init
, то возвращенное функцией
getppid
значение должно быть проверено перед отправкой сигнала.

16.4. Если удалить эти две строки, вызывается функция

select
. Но функция
select
немедленно завершится, поскольку соединение установлено и сокет открыт для записи. Эта проверка и оператор
goto
предотвращают ненужный вызов функции
select
.

16.5. Это может случиться, если сервер отправляет данные сразу, как только завершается его функция

accept
, и если узел клиента занят, когда приходит второй пакет трехэтапного рукопожатия для завершения соединения со стороны клиента (см. рис. 2.5). SMTP-серверы, например, немедленно отсылают клиенту сообщение по новому соединению, прежде чем произвести из него считывание.

Глава 17

17.1. Нет, это не имеет значения, поскольку первые три элемента объединения в листинге 17.1 являются структурами адреса сокета.

Глава 18

18.1. Элемент

sdl_nlen
будет равен 5, а элемент
sdl_alen
будет равен 8. Для этого требуется 21 байт, поэтому размер округляется до 24 байт [128, с. 89] в предположении, что используется 32-разрядная архитектура.

18.2. На этот сокет никогда не посылается ответ от ядра. Данный параметр сокета (

SO_USELOOPBACK
) определяет, посылает ли ядро ответ отправляющему процессу, как показано на с. 649-650 [128]. По умолчанию этот параметр включен, поскольку большинство процессов ожидают ответа. Но отключение данного параметра препятствует отправке ответов отправителю.

Глава 20

20.1. Если вы получаете большое количество ответов, они могут следовать каждый раз в разном порядке. Правда, отправляющий узел обычно выводится первым, поскольку дейтаграммы, направленные к нему или от него, не появляются в реальной сети.

Перейти на страницу:
Комментариев (0)
название