Чтение онлайн

на главную - закладки

Жанры

TCP/IP Архитектура, протоколы, реализация (включая IP версии 6 и IP Security)

Фейт Сидни М.

Шрифт:

На рис. 21.2 демонстрируется последовательность вызовов в типичном сеансе TCP. Вызовы socket, bind и listen обрабатываются очень быстро, и на них немедленно возвращается ответ.

Рис. 21.2. Последовательность программных вызовов в socket TCP

Вызовы accept, send и recv

предполагаются в режиме блокирования (что является их обычным значением по умолчанию). Вызов send блокируется и при переполнении выходного буфера TCP. Вызовы write и read можно использовать вместо send и recv.

21.6 Серверная программа TCP

Рассмотрим подробно пример серверной программы. Сервер предназначен для непрерывной работы. Он будет выполнять следующие действия:

1. Запрашивать у socket создание главного TCB и возвращать значение дескриптора socket, который будет идентифицировать этот TCB в последующих вызовах.

2. Вводить локальный адрес сервера socket в структуру данных программы.

3. Запрашивать связывание, при котором в TCB копируется локальный адрес socket.

4. Создавать очередь, которая сможет хранить сведения о пяти клиентах. Оставшиеся шаги повторяются многократно:

5. Ожидать запросов от клиентов. Когда появляется клиент, создавать для него новый TCB на основе копии главного TCB и записи в него адреса socket клиента и других параметров.

6. Создавать дочерний процесс для обслуживания клиента. Дочерний процесс будет наследовать новый TCB и обрабатывать все дальнейшие операции по связи с клиентом

(ожидать сообщений от клиента, записывать их и завершать работу).

Каждый шаг в программе объясняется в следующем разделе.

/* tcpserv.c

 * Для запуска программ ввести "tcpserv". */

/* Сначала включить набор стандартных заголовочных файлов. */

#include <sys/types.h>

#include <sys/socket.h>

#include <stdio.h>

#include <netinet/in.h>

#include <netdb.h>

#include <errno.h>

main {

 int sockMain, sockClient, length, child;

 struct sockaddr_in servAddr;

 /* 1. Создать главный блок управления пересылкой. */

 if ((sockMain = socket(AF_INET, SOCK_STREAM, 0)) < 0) {

perror("Сервер не может открыть главный socket.");

exit(1);

 }

 /* 2. Создать структуру данных для хранения локальных IP-адресов

* и портов, которые будут использованы. Предполагается прием

*
клиентских соединений от любых локальных IP-адресов

* (INADDR_ANY). Поскольку данный сервер не применяет

* общеизвестный порт, установить port = 0. Это позволит

* связать вызов с присвоением порта серверу и записать

* порт в TCB. */

 bzero((char *)&servAddr, sizeof(servAddr));

 servAddr.sin_family = AF_INET;

 servAddr.sin_addr.s_addr = htonl(INADDR_ANY);

 servAddr.sin_port = 0;

 /* 3. Связать запрос, выбор номера порта и

* запись его в TCB. */

 if (bind(sockMain, &servAddr, sizeof(servAddr))) {

perror("Связывание сервера неудачно.");

exit(1);

 }

 /* Чтобы увидеть номер порта, следует использовать

* функцию getsockname, чтобы скопировать порт в servAddr. */

 length = sizeof(servAddr);

 if (getsockname(sockMain, &servAddr, &length)) {

perror("Вызов getsockname неудачен.");

exit(1);

 }

 printf("СЕРВЕР: номер порта - %d\n", ntohs(servAddr.sin_port));

 /* 4. Создать очередь для хранения пяти клиентов. */

 listen(sockMain, 5);

 /* 5. Ожидать клиента. При разрешении возвратить новый

* дескриптор socket, который должен использоваться клиентом. */

 for(;;) {

if ((sockClient = accept(sockMain, 0, 0)) < 0) {

perror ("Неверный socket для клиента.");

exit(1);

}

/* 6. Создать дочерний процесс для обслуживания клиента. */

if ((child = fork) < 0)
{

perror("Ошибка создания дочернего процесса.");

exit(1);

}
else if (child == 0) /* Это код для исполнения дочернего процесса. */

{

close(sockMain); /* Дочерний процесс неинтересен для sockMain.*/

childWork(sockClient);

close(sockClient);

exit(0);

}

/* 7. Это родительский процесс. Его более не интересует

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

Газлайтер. Том 10

Володин Григорий
10. История Телепата
Фантастика:
боевая фантастика
5.00
рейтинг книги
Газлайтер. Том 10

На границе империй. Том 7. Часть 2

INDIGO
8. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
6.13
рейтинг книги
На границе империй. Том 7. Часть 2

Звездная Кровь. Изгой

Елисеев Алексей Станиславович
1. Звездная Кровь. Изгой
Фантастика:
боевая фантастика
попаданцы
рпг
5.00
рейтинг книги
Звездная Кровь. Изгой

Хозяин Теней 4

Петров Максим Николаевич
4. Безбожник
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Хозяин Теней 4

Картофельное счастье попаданки

Иконникова Ольга
Фантастика:
фэнтези
5.00
рейтинг книги
Картофельное счастье попаданки

Экзорцист: Проклятый металл. Жнец. Мор. Осквернитель

Корнев Павел Николаевич
Фантастика:
фэнтези
героическая фантастика
5.50
рейтинг книги
Экзорцист: Проклятый металл. Жнец. Мор. Осквернитель

Доктора вызывали? или Трудовые будни попаданки

Марей Соня
Фантастика:
юмористическая фантастика
попаданцы
5.00
рейтинг книги
Доктора вызывали? или Трудовые будни попаданки

Метатель

Тарасов Ник
1. Метатель
Фантастика:
боевая фантастика
попаданцы
рпг
фэнтези
фантастика: прочее
постапокалипсис
5.00
рейтинг книги
Метатель

Моя на одну ночь

Тоцка Тала
Любовные романы:
современные любовные романы
короткие любовные романы
5.50
рейтинг книги
Моя на одну ночь

Чехов. Книга 2

Гоблин (MeXXanik)
2. Адвокат Чехов
Фантастика:
фэнтези
альтернативная история
аниме
5.00
рейтинг книги
Чехов. Книга 2

Хозяин Теней 2

Петров Максим Николаевич
2. Безбожник
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Хозяин Теней 2

Сумеречный стрелок 7

Карелин Сергей Витальевич
7. Сумеречный стрелок
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Сумеречный стрелок 7

Жизнь под чужим солнцем

Михалкова Елена Ивановна
Детективы:
прочие детективы
9.10
рейтинг книги
Жизнь под чужим солнцем

Красноармеец

Поселягин Владимир Геннадьевич
1. Красноармеец
Фантастика:
боевая фантастика
попаданцы
4.60
рейтинг книги
Красноармеец