Создание однопотоковых параллельных серверов TCP 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Создание однопотоковых параллельных серверов TCP



Цель работы: изучить методы создания приложений, используя алгоритм обработки запросов однопотоковыми параллельными серверами.

 

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

 

Однопотоковые параллельные серверы

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

Однако на практике в некоторых серверах (например службы ECHO) квантование времени применяется редко. В этих случаях для активизации об- работки используется сам факт поступления данных. В основе такого решения лежит изучение структуры потоков данных, проходящих по объединенной сети. Данные поступают на сервер в виде пульсирующего трафика, а не устойчивого потока, поскольку базовая объединенная сеть доставляет данные в отдельных пакетах. Неравномерность трафика еще больше возрастает в связи с тем, что клиенты, как правило, отправляют данные в виде крупных блоков, чтобы каж- дый из сформированных в результате сегментов TCP мог занять всю дейта- грамму IP. На сервере каждый ведомый поток основную часть времени прово- дит в состоянии, заблокированном в вызове функции read (или recv), ожидая поступления следующей порции данных. Сразу после поступления данных происходит возврат управления из функции read (recv), и выполнение ведомого потока возобновляется. Ведомый поток вызывает функцию write (send) для пе- редачи данных обратно клиенту, а затем снова вызывает функцию read (recv) для перехода в состояние ожидания поступления следующей порции данных. Процессор сможет выдержать нагрузку по обработке данных, поступающих от многочисленных клиентов, не внося замедления, только в том случае, если он


будет способен завершить цикл чтения и записи одного потока до поступления данных для другого ведомого потока.

Безусловно, если нагрузка становится столь значительной, что процессор не может завершить выполнение одного запроса до поступления другого, прин- цип организации работы с квантованием времени становится более приемле- мым. Операционная система переключает процессор между всеми ведомыми потоками, имеющими данные, предназначенные для обработки. Однако в слу- чае простых служб, требующих небольшого объема обработки данных для об- служивания каждого запроса, велика вероятность того, что для активизации процесса обработки будет использоваться сам факт поступления данных.

Параллельные серверы, в которых на обработку каждого запроса требу- ется мало времени, часто выполняют обработку данных последовательно; при этом причиной активизации процесса обработки является сам факт поступле- ния данных. Квантование времени начинает использоваться только с того мо- мента, когда нагрузка становится настолько высокой, что процессор не может обрабатывать запросы последовательно.

Поскольку в результате изучения характера работы параллельного серве- ра стало очевидно, что он часто выполняет обработку данных последовательно, был сделан вывод, что для выполнения той же задачи может применяться один поток. Допустим, что один поток сервера обслуживает соединения TCP одно- временно с несколькими клиентами. Поток блокируется, ожидая поступления данных. Сразу после поступления данных через любое соединение поток акти- визируется, обрабатывает запрос и передает ответ. Затем он снова блокируется, ожидая поступления данных из другого соединения. При условии, что процес- сор работает достаточно быстро для того, чтобы выдержать нагрузку, возло- женную на сервер, однопотоковая версия сможет обслуживать соединения с та- ким же успехом, как и версия с несколькими потоками. Действительно, однопо- токовая реализация не требует переключения между контекстами потоков или процессов, поэтому она может даже выдержать более высокую нагрузку по сравнению с реализацией, в которой используются несколько потоков или про- цессов.

 

Использование функции select

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

На рисунке 6 показана схема организации работы и состав сокетов одно- потокового, параллельного сервера. Для управления обмена данными через все сокеты применяется один поток.


 

Рисунок 6 – Схема организации процессов сервера с установлением логического соединения, в котором параллельная работа обеспечивается с использованием одного потока, управляющего сразу

несколькими сокетами

 

По сути, один единственный поток должен выполнять обязанности и ве- дущего, и всех ведомых потоков. Он сопровождает набор сокетов, причём один из них (так называемый ведущий сокет) остается привязанным к общепринято- му порту, через который он должен принимать запросы на установление соеди- нения. Каждый из ведомых сокетов в наборе соответствует соединению, для которого ведомый поток должен обрабатывать запросы. Сервер передает набор дескрипторов сокетов функции select в качестве параметра и ожидает активиза- ции любого из них. После возврата управления функция select передает в вызы- вающий оператор битовую маску, которая указывает, какой из дескрипторов в наборе готов к работе. В сервере для принятия решения о том, с каким из деск- рипторов нужно продолжить работу, используется порядок их активизации.

Для определения того, какие операции (ведущего или ведомого потока) должны быть выполнены для данного дескриптора, в однопотоковом сервере используется сам дескриптор. Если к работе готов дескриптор, соответствую- щий ведущему сокету, сервер выполняет для него такие же операции, какие выполнил бы ведущий поток: он вызывает функцию accept с этим сокетом для получения нового соединения. Если же к работе готов дескриптор, соответст- вующий ведомому сокету, сервер выполняет операцию ведомого потока: он вы- зывает функцию read (recv) для получения запроса, а затем отвечает на этот за- прос.


Методические указания по созданию однопотокового параллельного сервера с установлением логического соединения

Рассмотрим процесс создания такого сервера на следующем примере. Осуществить взаимодействие клиента и сервера на основе протокола

TCP. Реализовать параллельное соединение с использованием одного потока. На сервере хранится список студентов. Каждая запись списка содержит сле- дующую информацию о студенте:

- ФИО студента;

- номер группы;

- размер стипендии;

- оценки по N предметам.

Таких записей должно быть не менее 5-ти.

По личному запросу клиент получает от сервера список только тех сту- дентов, которые не имеют оценки 3. Предусмотреть возможность редактирова- ния записей списка клиентом.

Рассмотрим серверную часть. Серверная часть

#include <sys/types.h> #include<sys/socket.h> #include<sys/signal.h>

 

//#include<sys/resource.h> #include<netinet/in.h>

 

#include <string.h> #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <netdb.h>

 

const int

NameL = 33,

GroupL = 10,

payL =10;

 

struct Student{

char name[NameL+1]; char group[GroupL+1]; char pay[payL+1]; char mark[5];

} st[5];

 

int DoProcess(int fd){ puts("rabotaet doProcess");

long int i,num,t,newS;


int m; char p;

char buf[256],b[256]; while (true){

recv(newS,buf,sizeof(buf),0);

 

p=buf[0]; puts(buf); switch(p){ case '1':

buf[0]='\0';

for (i=1;i<=5;i++)

if (st[i].mark[1]!='3' && st[i].mark[2]!='3' &&

st[i].mark[3]!='3' z&& st[i].mark[4]!='3'){

strcat(buf,st[i].name);

strcat(buf,"\n");

}

send(newS,buf,sizeof(buf),0); puts(buf);

break; case '2':

recv(newS,buf,sizeof(buf),0); num=atoi(buf); printf("%d\n",num); recv(newS,buf,sizeof(buf),0); strcpy(st[num].name,buf);

 

recv(newS,buf,sizeof(buf),0); strcpy(st[num].group,buf);

 

recv(newS,buf,sizeof(buf),0); strcpy(st[num].pay,buf);

 

recv(newS,buf,sizeof(buf),0); st[num].mark[1]=buf[0]; recv(newS,buf,sizeof(buf),0); st[num].mark[2]=buf[0]; recv(newS,buf,sizeof(buf),0); st[num].mark[3]=buf[0]; recv(newS,buf,sizeof(buf),0); st[num].mark[4]=buf[0];

 

break; case '3':

for (i=1;i<=5;i++){ buf[0]='\0';

strcat(buf,st[i].name);strcat(buf," ");

strcat(buf,st[i].group);strcat(buf," ");

strcat(buf,st[i].pay);strcat(buf," "); b[0]=st[i].mark[1];

strcat(buf,b);strcat(buf," ");

b[0]=st[i].mark[2];


strcat(buf,b);strcat(buf," ");

b[0]=st[i].mark[3];

strcat(buf,b);strcat(buf," ");

b[0]=st[i].mark[4];

strcat(buf,b);strcat(buf,"\n");

 

send(newS,buf,sizeof(buf),0);

}

break; case '4':

exit(0);

}

}

}

 

int main(){

strcpy(st[1].name,"Ivanov Ivan Ivanovich"); strcpy(st[1].group,"111111");

strcpy(st[1].pay,"111111");

st[1].mark[1]='4';

st[1].mark[2]='2';

st[1].mark[3]='5';

st[1].mark[4]='5';

 

strcpy(st[2].name,"petrov petr petrovich"); strcpy(st[2].group,"222222");

strcpy(st[2].pay,"222222");

st[2].mark[1]='4';

st[2].mark[2]='2';

st[2].mark[3]='4';

st[2].mark[4]='5';

 

strcpy(st[3].name,"sidorov sidor sidorovich"); strcpy(st[3].group,"333333");

strcpy(st[3].pay,"333333");

st[3].mark[1]='5';

st[3].mark[2]='1';

st[3].mark[3]='4';

st[3].mark[4]='2';

 

strcpy(st[4].name,"brusnikin igor igorevich"); strcpy(st[4].group,"444444");

strcpy(st[4].pay,"444444");

st[4].mark[1]='2';

st[4].mark[2]='3';

st[4].mark[3]='5';

st[4].mark[4]='2';

 

strcpy(st[5].name,"klukvin yurij yurjevich"); strcpy(st[5].group,"555555");

strcpy(st[5].pay,"555555");

st[5].mark[1]='4';


st[5].mark[2]='1';

st[5].mark[3]='1';

st[5].mark[4]='3';

 

fd_set rfds; fd_set afds;

 

struct sockaddr_in sin; int s;

 

memset(&sin,0,sizeof(sin)); sin.sin_family=AF_INET; sin.sin_port=htons(7500); sin.sin_addr.s_addr=htonl(INADDR_ANY);

 

 

int alen; int fd,nfds;

 

s=socket(AF_INET, SOCK_STREAM,0);

bind(s,(struct sockaddr *)&sin, sizeof(sin)); listen(s,5);

 

nfds=getdtablesize(); FD_ZERO(&afds); FD_SET(s,&afds);

int newS; int k; while(true){

memcpy(&rfds,&afds,sizeof(rfds)); select(nfds,&rfds,NULL,NULL,(struct timeval*)0);

if (FD_ISSET(s,&rfds)){ alen=sizeof(sin);

int temp=(int)alen;

newS=accept(s,(struct sockaddr*)&sin,&temp); FD_SET(s,&afds);

}

 

for (fd=0;fd<nfds;fd++)

if (fd!=s && FD_ISSET(fd,&rfds)) if (DoProcess(fd)==0){

(void)close(fd); FD_CLR(fd,&afds);

}

}

return 0;

}


Индивидуальные задания

Разработать приложение, реализующее архитектуру «клиент-сервер». Не- обходимо реализовать параллельный сервер с установлением логического со- единения (TCP), использующий отдельный процесс для обработки запросов клиентов. Логику взаимодействия клиента и сервера реализовать так, как ука- зано в индивидуальном задании.

1. Сервер хранит информацию о домашней библиотеке. Клиент имеет возможность работы с произвольным числом книг, поиска книги по какому- либо признаку (например, по автору или по году издания), добавления книг в библиотеку, удаления книг из нее, сортировки по разным полям. Программа клиента должна содержать меню, позволяющее осуществлять указанные дейст- вия на сервере.

2. Сервер хранит информацию из записной книжки. Клиент имеет воз- можность работы с произвольным числом записей, поиска записи по какому- либо признаку (например, по фамилии, дате рождения или номеру телефона), добавления и удаления записей, сортировки по разным полям. Программа кли- ента должна содержать меню, позволяющее осуществлять указанные действия на сервере.

3. Сервер хранит информацию о студенческой группе. Клиент имеет воз- можность работы с переменным числом студентов, поиска студента по какому- либо признаку (например, по фамилии, дате рождения или номеру телефона), добавления и удаления записей, сортировки по разным полям. Программа кли- ента должна содержать меню, позволяющее осуществлять указанные действия на сервере.

4. Сервер хранит информацию о некоторой коллекции компакт-дисков. Клиент имеет возможность просмотра, добавления, удаления информации, сор- тировки по разным полям. Программа клиента должна содержать меню, позво- ляющее осуществлять указанные действия на сервере.

5. Сервер хранит информацию о лицевых счетах вкладчиков банковского учреждения. Запись о каждом вкладчике состоит из информации: фамилия, дата операции, сумма вклада, общая сумма. Клиент имеет возможность пополнения и изъятия данных о вкладчиках, ведения текущих счетов, сортировки по раз- ным полям. Программа клиента должна содержать меню, позволяющее осуще- ствлять указанные действия на сервере.

6. Сервер хранит информацию о персонале: фамилия, должность, зарпла- та, дата рождения. Клиент имеет возможность добавления, изменения, удаления информации, сортировки по разным полям. Программа клиента должна содер- жать меню, позволяющее осуществлять указанные действия на сервере.

7. Сервер хранит информацию о плоских геометрических фигурах: пря- моугольник, треугольник, окружность. Клиент имеет возможность просмотра информации, редактирования, удаления, получения информации о площади и периметре указанных фигур. Программа клиента должна содержать меню, по- зволяющее осуществлять указанные действия на сервере.


8. Сервер хранит два одномерных массива строк фиксированной длины. Клиент имеет возможность обращения к отдельным строкам массивов по ин- дексам, выполнения операций поэлементного сцепления двух массивов с обра- зованием нового массива, слияния двух массивов с исключением повторяю- щихся элементов, вывода на экран элемента массива по заданному индексу и всех массивов, редактирования массивов. Программа клиента должна содер- жать меню, позволяющее осуществлять указанные действия на сервере.

9. Сервер хранит предметный указатель, каждая компонента которого со- держит слово и номера страниц, где это слово встречается. Количество номеров страниц, относящихся к одному слову, от одного до десяти. Клиент имеет воз- можность формирования указателя с клавиатуры и из файла, вывода указателя, вывода номеров страниц для заданного слова, удаления элемента из указателя. Программа клиента должна содержать меню, позволяющее осуществлять ука- занные действия на сервере.

10. Сервер хранит некоторую матрицу произвольного размера. Клиент имеет возможность формирования элементов матрицы, редактирования эле- ментов матрицы, изменения числа строк и столбцов матрицы, вывода на экран подматрицы любого размера и всей матрицы. Программа клиента должна со- держать меню, позволяющее осуществлять указанные действия на сервере.

11. Сервер хранит информацию о клиентах некоторой торговой организа- ции. Клиент имеет возможность добавления, удаления, редактирования, сорти- ровки информации на сервере, а также поиска по заданным полям. Программа клиента должна содержать меню, позволяющее осуществлять указанные дейст- вия на сервере.

12. Сервер хранит одномерные массивы целых чисел (вектора). Клиент имеет возможность формирования элементов векторов, редактирования, удале- ния, сортировки, а также поэлементного сложения и вычитания векторов с оди- наковыми границами индексов, умножения и деления всех элементов векторов на скаляр, вывода максимального и минимального элементов векторов. Про- грамма клиента должна содержать меню, позволяющее осуществлять указан- ные действия на сервере.

13. Север хранит информацию о результатах студенческой сессии. Кли- ент имеет возможность просмотра, редактирования, удаления информации, по- иска студента по какому-либо признаку (например, по фамилии, оценкам по предмету), сортировки по разным полям. Программа клиента должна содержать меню, позволяющее осуществлять указанные действия на сервере.

14. Сервер хранит информацию о наличии билетов к кассе кинотеатра. Клиент имеет возможность просмотра, добавления, удаления информации, сор- тировки по разным полям, а также поиска по заданному условию (например, по фильму, по стоимости билета, по времени начала сеанса). Программа клиента должна содержать меню, позволяющее осуществлять указанные действия на сервере.

15. Сервер хранит список вопросов по некоторой дисциплине (например компьютерные сети), и варианты ответов на них (на каждый вопрос – три отве-


та, среди которых только один правильный). Клиент имеет возможность про- смотра вопросов и выбора правильного ответа на них. Сервер проверяет пра- вильность ответов клиента и выставляет ему оценку. Клиент также имеет воз- можность редактирования вопросов и ответов на сервере. Программа клиента должна содержать меню, позволяющее осуществлять указанные действия на сервере.

 

 

Контрольные вопросы

1. Принцип работы механизма квантования времени организации работы сервера.

2. В каком виде данные поступают на сервер в том случае, если метод квантования времени не применяется?

3. Что происходит после поступления на сервер всех данных?

4. Для чего используется функция write (send)?

5. При каком условии процессор сможет выдержать нагрузку по обра- ботке данных, поступающих от многочисленных клиентов, не внося никаких замедлений?

6. В каком случае используется функция select?


Лабораторная работа №6



Поделиться:


Последнее изменение этой страницы: 2019-12-15; просмотров: 546; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.119.104.238 (0.118 с.)