Вход/Регистрация
UNIX: разработка сетевых приложений
вернуться

Стивенс Уильям Ричард

Шрифт:

Во всех рассматриваемых далее примерах присутствуют зависящие от протоколов жестко заданные (hard coded) константы, такие как адреса и порты. Это обусловлено двумя причинами. Во-первых, нам необходимо точно понимать, что нужно хранить в структурах адресов, относящихся к конкретным протоколам. Во-вторых, мы еще не рассмотрели библиотечные функции, которые сделали бы наши программы более переносимыми. Эти функции рассматриваются в главе 11.

В последующих главах код клиента и сервера будет претерпевать многочисленные изменения, по мере того как вы будете больше узнавать о сетевом программировании (см. табл. 1.3 и 1.4).

5.2. Эхо-сервер TCP: функция main

Наши клиент и сервер TCP используют функции, показанные на рис. 4.1. Программа параллельного сервера представлена в листинге 5.1 [1] .

Листинг 5.1. Эхо-сервер TCP (улучшенный в листинге 5.9)

//tcpcliserv/tcpserv01.с

1 #include "unp.h"

2 int

3 main(int argc, char **argv)

1

Все исходные коды программ, опубликованные в этой книге, вы можете найти по адресу http://www.piter.com.

4 {

5 int listenfd, connfd;

6 pid_t childpid;

7 socklen_t clilen;

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) для обработки запроса клиента.

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

Функция

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

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

//lib/str_echo.c

1 #include "unp.h"

2 void

3 str_echo(int sockfd)

  • Читать дальше
  • 1
  • ...
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: