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

 8  struct sockaddr_in cliaddr, servaddr;

 9  listenfd = Socket(AF_INET, SOCK_STREAM, 0);

10  bzero(&servaddr, sizeof(servaddr));

11  servaddr.sin_family = AF_INET;

12  servaddr.sin_addr.s_addr = htonl(INADDR_ANY);

13  servaddr.sin_port = htons(SERV_PORT);

14  Bind(listenfd, (SA*)&servaddr, sizeof(servaddr));

15  Listen(listenfd, LISTENQ);

16  for (;;) {

17   clilen = sizeof(cliaddr);

18   connfd = Accept(listenfd, (SA*)&cliadd, &clilen);

19   if ((childpid = Fork()) == 0) { /* дочерний процесс */

20    Close(listenfd); /* закрываем прослушиваемый сокет */

21    str_echo(connfd); /* обрабатываем запрос */

22    exit(0);

23   }

24   Close(connfd); /* родительский процесс закрывает

                     присоединенный сокет */

25  }

26 }

Создание сокета, связывание с известным портом сервера

9-15 Создается сокет TCP. В структуру адреса сокета Интернета записывается универсальный адрес (INADDR_ANY) и номер заранее известного порта сервера (SERV_PORT, который определен как 9877 в нашем заголовочном файле unp.h). В результате связывания с универсальным адресом системе сообщается, что мы примем соединение, предназначенное для любого локального интерфейса в том случае, если система имеет несколько сетевых интерфейсов. Наш выбор номера порта TCP основан на рис. 2.10. Он должен быть больше 1023 (нам не нужен зарезервированный порт), больше 5000 (чтобы не допустить конфликта с динамически назначаемыми портами, которые выделяются многими реализациями, происходящими от Беркли), меньше 49 152 (чтобы избежать конфликта с «правильным» диапазоном динамически назначаемых портов) и не должен конфликтовать ни с одним зарегистрированным портом. Сокет преобразуется в прослушиваемый при помощи функции listen.

Ожидание завершения клиентского соединения

17-18 Сервер блокируется в вызове функции accept, ожидая подключения клиента.

Параллельный сервер

19-24 Для каждого клиента функция fork порождает дочерний процесс, и дочерний процесс обслуживает запрос этого клиента. Как мы говорили в разделе 4.8, дочерний процесс закрывает прослушиваемый сокет, а родительский процесс закрывает присоединенный сокет. Затем дочерний процесс вызывает функцию str_echo (см. листинг 5.2) для обработки запроса клиента.

<p>5.3. Эхо-сервер TCP: функция str_echo</p>

Функция str_echo, показанная в листинге 5.2, выполняет серверную обработку запроса клиента: считывание строк от клиента и отражение их обратно клиенту.

Листинг 5.2. Функция str_echo: отраженные строки на сокете

//lib/str_echo.c

 1 #include "unp.h"

 2 void

 3 str_echo(int sockfd)

 4 {

 5  ssize_t n;

 6  char buf[MAXLINE];

 7  for (;;) {

 8   if ((n = read(sockfd, buf, MAXLINE)) > 0)

 9    return; /* соединение закрыто с другого конца */

10   Writen(sockfd, line, n);

11  }

12 }

Чтение строки и ее отражение

7-11 Функция read считывает очередную строку из сокета, после чего строка отражается обратно клиенту с помощью функции writen. Если клиент закрывает соединение (нормальный сценарий), то при получении клиентского сегмента FIN функция дочернего процесса read возвращает нуль. После этого происходит возврат из функции str_echo и далее завершается дочерний процесс, приведенный в листинге 5.1.

<p>5.4. Эхо-клиент TCP: функция main</p>

В листинге 5.3 показана функция main TCP-клиента.

Листинг 5.3. Эхо-клиент TCP

//tcpcliserv/tcpcli01.c

 1 #include "unp.h"

 2 int

 3 main(int argc, char **argv)

 4 {

 5  int sockfd;

 6  struct sockaddr_in servaddr;

 7  if (argc != 2)

 8   err_quit("usage: tcpcli ");

 9  sockfd = Socket(AF_INET, SOCK_STREAM, 0);

10  bzero(&servaddr. sizeof(servaddr));

11  servaddr.sin_family = AF_INET;

12  servaddr.sin_port = htons(SERV_PORT);

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

Все книги серии Мастер-класс

Секреты резьбы по дереву
Секреты резьбы по дереву

Изделия из древесины и материалов, имитирующих ее текстуру, привычным образом окружают нас в повседневной жизни, поэтому мы относимся к ней как к чему-то обыденному. Но как только ее коснется умелая рука мастера резьбы по дереву, рождается произведение искусства и раскрываются такие качества древесины, как богатая фактура, разнообразие цветов, особая теплота. Эта книга поможет читателю открыть для себя удивительный мир творчества и познать секреты резьбы по дереву. Автор надеется, что начинающие резчики найдут в ней интересный и полезный материал, который позволит им стать мастерами. В приложении представлены рисунки орнаментов и различных узоров, которые на первых порах можно копировать, а по мере приобретения навыка на их основе разрабатывать свои образцы.

Галина Алексеевна Серикова

Сделай сам / Хобби и ремесла / Руководства / Дом и досуг / Словари и Энциклопедии

Похожие книги