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


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

Case '2':recv(newS,buf,sizeof(buf),0);// Таб.номер



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

break;

Case '3':recv(newS,buf,sizeof(buf),0);// Доход

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

break;

Case '4':recv(newS,buf,sizeof(buf),0);// Ставка налога

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

}

break;

case '3':

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

buf[0]='\0';

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

strcat(buf,em[i].number);strcat(buf," ");

strcat(buf,em[i].income);strcat(buf," ");

strcat(buf,em[i].tax);strcat(buf,"\n");

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

}

break;

case '4':

exit(0);

}

}

}


Поскольку в параллельных серверах для динамического создания процессов используется функция fork() (см. ниже), они являются потенциальным источником проблемы не полностью завершившихся процессов (процессов, информация о которых остается в системных таблицах). В системе Linux эта проблема решается путем передачи специального сигнала родительскому процессу после завершения работы каждого дочернего процесса. Завершившийся процесс остается в виде так называемого процесса-зомби до тех пор, пока родительским процессом не будет выполнен системный вызов wait3. Для полного завершения дочернего процесса (т.е. для уничтожения процесса-зомби) в рассматриваемом примере перехватывается сигнал завершения дочернего процесса и выполняется функция обработки этого сигнала. Операционной системе дается указание, что для ведущего процесса сервера при получении каждого сигнала о завершении работы дочернего процесса (сигнал SIGCHLD) должна быть выполнена функция reaper(), в виде следующего вызова, который в нашей программе осуществляется в main:

 

signal (SIGCHLD, reaper);

 

После вызова функции signal() система автоматически вызывает функцию reaper() при получении процессом сервера каждого сигнала SIGCHLD.

Функция reaper() вызывает системную функцию wait3() для полного завершения дочернего процесса, закончившего свою работу. Функция wait3() остается заблокированной до тех пор, пока не произойдет завершение работы одного или нескольких дочерних процесса (по любой причине). Эта функция возвращает значение структуры status, которую можно проанализировать для получения дополнительной информации о завершившемся процессе. Поскольку данная программа вызывает функцию wait3() при получении сигнала SIGCHLD, вызов этой функции всегда происходит только после завершения работы дочернего процесса. Для предотвращения возникновения в сервере тупиковой ситуации в случае ошибочного вызова в программе используется параметр WNOHANG, который указывает, что функция wait3 не должна блокироваться в ожидании завершения какого-либо процесса. Вместо этого возврат управления после вызова происходит немедленно, даже если не произошел выход из какого-либо процесса.

void reaper(int sig){

int status;

while (wait3(&status,WNOHANG,(struct rusage*)0)>=0);

}

int main(){

strcpy(em[1].name,"Sergeev Sergei Sergeevich");

strcpy(em[1].number,"1");

strcpy(em[1].income,"100000");

strcpy(em[1].tax,"10");

strcpy(em[2].name,"Ivanov Ivan Ivanovich");

strcpy(em[2].number,"2");

strcpy(em[2].income,"200000");

strcpy(em[2].tax,"20");

strcpy(em[3].name,"Vladimirov Vladimir Vladimirovich");

strcpy(em[3].number,"3");

strcpy(em[3].income,"300000");

strcpy(em[3].tax,"30");

strcpy(em[4].name,"Sidorov Sidor Sidorovich ");

strcpy(em[4].number,"4");

strcpy(em[4].income,"400000");

strcpy(em[4].tax,"40");

strcpy(em[5].name,"Vasilev Vasilii Vasilievich");

strcpy(em[5].number,"5");

strcpy(em[5].income,"500000");

strcpy(em[5].tax,"50");

struct sockaddr_in local;

Int s,

NewS,

rc;

local.sin_family=AF_INET;

local.sin_port=htons(7500);

local.sin_addr.s_addr=htonl(INADDR_ANY);

s=socket(AF_INET, SOCK_STREAM,0);

rc=bind(s,(struct sockaddr *)&local, sizeof(local));

rc=listen(s,5);

(void)signal(SIGCHLD,reaper);

while(true){

newS=accept(s,NULL,NULL);

switch (fork()){

case 0:

(void)close(s);

exit(Func(newS));

default:

(void)close(newS);

}

}

return 0;

}

КЛИЕНТСКАЯ часть

#include <sys/types.h>

#include<sys/socket.h>

#include<netinet/in.h>

#include<arpa/inet.h>

#include<stdio.h>

#include <stdlib.h>

#include <string.h>

int main (){

struct sockaddr_in peer;

int s,t,t1;

int rc;

char buf[256],p,p1,b[256];;

peer.sin_family=AF_INET;

peer.sin_port=htons(7500);

peer.sin_addr.s_addr=inet_addr("127.0.0.1");

s=socket(AF_INET,SOCK_STREAM,0);

rc=connect(s,(struct sockaddr *)&peer,sizeof(peer));

while(true){

//Выбор пункта меню и отправка его серверу

puts("Choose:");

puts("\t1 - Select");

puts("\t2 - Edit");

puts("\t3 - View");

puts("\t4 - Exit");

scanf("%s",buf);

buf[1]='\0';

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

p=buf[0];

switch (p){

Case '1'://Выбрать

puts("kol-vo months (1-12) :");scanf("%s",buf);

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

puts("Symbol: ");scanf("%s",buf);

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

printf("Sum of taxes: ");

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

for (t=0;buf[t+3];t++) printf("%c",buf[t]);

printf(".");

for (t1=t;buf[t1];t1++) printf("%c",buf[t1]);

printf("\n");

break;

 




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

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