Помощничек
Главная | Обратная связь


Археология
Архитектура
Астрономия
Аудит
Биология
Ботаника
Бухгалтерский учёт
Войное дело
Генетика
География
Геология
Дизайн
Искусство
История
Кино
Кулинария
Культура
Литература
Математика
Медицина
Металлургия
Мифология
Музыка
Психология
Религия
Спорт
Строительство
Техника
Транспорт
Туризм
Усадьба
Физика
Фотография
Химия
Экология
Электричество
Электроника
Энергетика

Recv(newS,buf,sizeof(buf),0);// Имя



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

Создание клиент-серверных приложений с установлением логического соединения (TCP/IP), используя алгоритм параллельной обработки запросов (отдельный процесс для обработки каждого запроса)

Цель работы – изучить методы создания клиент-серверных приложений, используя однопотоковые параллельные серверы (TCP).

 

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

Последовательная реализация сервера, может оказаться неудовлетворительной, поскольку клиенты будут вынуждены ждать завершения обработки всех предыдущих запросов на установление соединения. Если клиент решит передать большие объемы данных (например, несколько мегабайт), последовательный сервер отложит обслуживание всех других клиентов до тех пор, пока не выполнит этот запрос.

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

 

 

Рис. 4.1. Схема организации процессов параллельного сервера с установлением логического соединения, в котором используются однопотоковые процессы

 

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

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

 

Методические указания

 

 

Рассмотрим все описанное выше на конкретном примере:

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

- Ф. И. О. сотрудника;

- табельный номер;

- доход в месяц;

- ставка налогов, отчисляемых в бюджет.

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

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

 

Решение этой задачи подразумевает использование компилятора языка С++ gcc, поставляемого вместе с эмулятором операционной системы Unix – Cygwin (см. приложение 1).

 

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

 

СЕРВЕРНАЯ часть.

// Подключение необходимых библиотек для работы с пакетом Cygwin

#include <sys/types.h>

#include<sys/socket.h>

#include<sys/signal.h>

#include<sys/wait.h>

#include<sys/resource.h>

#include<netinet/in.h>

#include <string.h>

#include <stdio.h>

#include <unistd.h>

#include <stdlib.h>

struct Employee{

char name[35];

char number[10];

char income[10];

char tax[4];

} em[5];

// процедура для обслуживания соединения

int Func(int newS){

long int i,num,t, mon, doh, nal;

float sum;

int m;

char p,p1,s;

char buf[256],b[256];

while (true){

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

p=buf[0];

switch(p){

case '1':

buf[0]='\0';

sum=0;

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

mon=atoi(buf);

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

s=buf[0];

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

if (em[i].name[0]==s){

nal=atoi(em[i].tax);

doh=atoi(em[i].income);

printf("mon %d\n",mon);

sum=sum+(nal*doh*mon)/100.0;

}

int* decpt,*sgn;

printf("%f\n",sum);

strcpy(buf,fcvt(sum,3,decpt,sgn));

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);

p1=buf[0];

switch(p1){

case '1':

recv(newS,buf,sizeof(buf),0);// Имя

strcpy(em[num].name,buf);

break;

 




Поиск по сайту:

©2015-2020 studopedya.ru Все права принадлежат авторам размещенных материалов.