21.6 Серверная программа TCP
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 ", 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. Это родительский процесс. Его более не интересует
* socket клиента, поскольку его обслуживание передано
* дочернему процессу. Родительский процесс закрывает свой элемент для
* socket клиента и переходит на цикл приема новых accept(). */
close(sockClient);
}
}
/* Дочерний процесс читает один поступивший буфер, распечатывает
* сообщение и завершается. */
#define BUFLEN 81
int childWork(sockClient)
int sockClient;
{
char buf[BUFLEN];
int msgLength;
/* 8. Опустошить буфер. Затем вывести recv для получения сообщения от клиента. */
bzero(buf, BUFLEN);
if ((msgLength = recv(sockClient, buf, BUFLEN, 0)) < 0) {
perror("Плохое получение дочерним процессом.");
exit(1);
}
printf ("SERVER: Socket для клиента - %d ", sockClient);
printf ("SERVER: Длина сообщения - %d ", msgLength);
printf ("SERVER: Сообщение: %s ", buf);
}
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКЧитайте также
1.4. Клиентская и серверная оптимизация: сходство и различия
1.4. Клиентская и серверная оптимизация: сходство и различия Клиентская оптимизация оперирует двумя основными принципами: меньше данных и меньше соединений. Но именно эти принципы помогают уменьшить нагрузку на сам сервер. Давайте посмотрим, как это происходит и как
Программа
Программа Программа – это последовательность машинных инструкций (системы команд, понятных процессору), предназначенная для выполнения определенной задачи. Как правило, программа оформлена в виде одного или нескольких исполняемых файлов, которые после установки
4.7.1. Программа tar
4.7.1. Программа tar У читателя, привыкшего к архиваторам типа arj, которые собирают файлы в единый архив и сразу "сжимают" их, может возникнуть вопрос "А зачем использовать две программы?” Все дело в том, что tar расшифровывается как Tape ARchiver, он не сжимает данные, а лишь объединяет
10.2. Программа rpm
10.2. Программа rpm Название этой программы (или команды) является аббревиатурой от Redhat Package Manager. Такая расшифровка дается в большинстве книг и руководств по Linux и кажется мне более правильной и логичной, хотя в главе 6 "The Official Red Hat Linux Reference Guide" говорится: "The RPM Package Manager (RPM), is an open
12.2.3 Программа gv
12.2.3 Программа gv Программа gv (или ghostview) разработана Иоганнесом Плассом (Johannes Plass) и предназначена для просмотра файлов формата PostScript и PDF (рис. 12.2).После ее запуска без указания имени файла основное окно программы будет пустым. Чтобы открыть какой-то файл, надо щелкнуть по
13.3.2 Программа ftp
13.3.2 Программа ftp Программа ftp - это пользовательский интерфейс к стандартному протоколу передачи файлов по Интернету - File Transfer Protocol. Программа позволяет передавать файлы на удаленный компьютер и получать файлы с удаленного компьютера. Однако, введя команду ftp, вы
2.6.2. Программа RPM
2.6.2. Программа RPM Установка программного обеспечения в дистрибутивах Red Hat и Mandrake производится с помощью программы rpm. RPM (red hat package manager) — это менеджер пакетов Red Hat. Несмотря на то, что в названии присутствует «Red Hat», он полностью предназначен работать как открытая пакетная
П1.1. Программа AVZ
П1.1. Программа AVZ Программа AVZ (Антивирус Зайцева) – очень полезная утилита, и не раз меня выручала еще со времен Windows XP. Тогда я использовал антивирус Касперского, который не умел работать в безопасном режиме. Получалось так – все, что пропустил основной антивирус, в
6. Программа обучения
6. Программа обучения Расскажите, что находится внутри продукта, как построено обучение, и покажите блоки тем, списки – пункты программы. «Вы узнаете три способа, как сделать то, семь секретов, как сделать это». Причем вы не только рассказываете, что внутри, но и то, что это
Программа
Программа Ниже приводится короткая программа, позволяющая узнавать номер кода символа даже в том случае, если на вашей машине не используется код ASCII. main( ) /* определяет номер кода символа */{ char ch; printf(" Введите, пожалуйста, символ . "); scanf(" %c", &ch); /* ввод
9.3. Программа apt-get
9.3. Программа apt-get Предположим, у вас есть пакет package.deb. При его установке обнаружилось, что он требует наличия пакета lib.deb, который у вас не установлен. Что ж, вы находите в Интернете отсутствующий пакет, устанавливаете его способом, описанным в разд. 9.2 (то есть применяя
20.3. Программа bum
20.3. Программа bum Ранее в Ubuntu имелась программа Службы (в программной группе Система | Администрирование), позволяющая включать/отключать системные сервисы. В современных версиях Ubuntu такой программы нет. Зато можно установить программу Boot-Up Manager, которая даже лучше, чем
4.5.1. Программа 1
4.5.1. Программа 1 Вначале нужно выбрать способ представления позиции на доске. Один из наиболее естественных способов — представить позицию в виде списка из восьми элементов, каждый из которых соответствует одному из ферзей. Каждый такой элемент будет описывать то поле
4.5.2. Программа 2
4.5.2. Программа 2 В соответствии с принятым в программе 1 представлением доски каждое решение имело вид[1/Y1, 2/Y2, 3/Y3, ..., 8/Y8]так как ферзи расставлялись попросту в последовательных вертикалях. Никакая информация не была бы потеряна, если бы X-координаты были пропущены. Поэтому
4.5.3. Программа 3
4.5.3. Программа 3 Наша третья программа для задачи о восьми ферзях опирается на следующие соображения. Каждый ферзь должен быть размещен на некотором поле, т.е. на некоторой вертикали, некоторой горизонтали, а также на пересечении каких-нибудь двух диагоналей. Для того,
Программа Nero Express Лучшая программа для записи дисков
Программа Nero Express Лучшая программа для записи дисков Записывать диски средствами Windows неинтересно. Во-первых, скучно, а во-вторых, вам недоступны какие-либо настройки записи, вы даже не можете указать скорость, не говоря уже о выборе формата диска, методе записи. Вот