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

Порядок выполнения. Создать три потока

Читайте также:
  1. I. Задания для обязательного выполнения
  2. I. Задания для обязательного выполнения
  3. I. Задания для обязательного выполнения
  4. II. Порядок заповнення граф декларації громадянином
  5. II. Порядок и условия предоставления целевого жилищного займа для приобретения жилого помещения (жилых помещений) под залог приобретаемого жилого помещения (жилых помещений)
  6. II. Порядок поставки
  7. II. Порядок формирования экспертных групп, организация экспертизы заявленных на Конкурс проектов и регламент работы Конкурсной комиссии

Создать три потока. Осуществить обработку сообщений поступающих от клиентов в виде: typedef struct{

int mesType; //тип сообщения

char msg[512];//сообщение

}TMessage

TMessage msg

Потоки реализовать следующим на следующем примере

void * thread1(void *pVal)

{

char *pch = "thread1";

int rcvid;//идентификатор отправителя

TMessage msg;

while(1){

//получение сообщения от клиента

rcvid = MsgReceive(g_chid, &msg, sizeof(msg), NULL);

printf("server,%s:: %s \n",pch,msg.msg);

printf("server,%s: id client - rcvid = %X\n",pch, rcvid);

print_time();//определение времени начала обработки поступившего сообщения

sleep(10);

msg.msg[0] = '\0';

switch(g_msg.mesType){

case 0: {

//ответ сервера

msg.mesType = 3;

strcpy(msg.msg,pch);

break;

}

case 1:{

msg.mesType = 4;

msg.msg[0] = '\0';

break;

}

}

printf("server,%s \n",pch);

print_time();//определение времени завершения обработки поступившего сообщения

MsgReply(rcvid, EOK, &msg, sizeof(msg));

}

}

Пример клиента.

 

#include <stdio.h>

#include <sys/neutrino.h>

#include <string.h>

#include <errno.h>

#include <sys/types.h>

#include <process.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <stdlib.h>

bool parse(char *pbuff, char **ppToken1, char **ppToken2)

{

*ppToken1 = pbuff;

char *pch = strchr(pbuff,'/');

if(pch){

*pch = '\0';

pch++;

*ppToken2 = pch;

}

else

return false;

return true;

}

void client(void *not_used)

{

char *smsg = "client message"; // сообщение клиента

char rmsg[200]; //ответ сервера

int cid; //идентификатор соединения

int pid; //дескриптор процесса

int chid; //идентификатор канала

char *ppid;

char *pchid;

Для того чтобы подключиться к серверу клиент вызывает функцию ConnectAttach(). Значения PID и CHID, которые используются в этой функции, клиент считывает из файла "/etc/mes2.pid", заполняемого процессом сервера.

//считывание из файла pid/chid

char *pname_file = "/etc/mes2.pid";

int fd = open(pname_file, O_RDONLY);

if (fd == -1){

печать сообщение об ошибке открытия файла

}

char buff[30];

int size_read = read(fd, buff, sizeof(buff));

if(size_read == -1){

печать сообщение об ошибке чтения файла

}

if(!parse(buff, &ppid, &pchid)){

печать сообщение об ошибке обработки данных

}

pid = atoi(ppid);

chid = atoi(pchid);

//присоединение процесса клиента к серверу pid и каналу chid

cid = ConnectAttach(0, pid, chid, 0, 0);

if(cid == -1){

печать сообщение об ошибке присоединение процесса клиента к серверу; return;

}

Для отправки сообщения серверу клиент использует функцию MsgSend().

int MsgSend(int coid, //Идентификатор соединения

const void *smsg, //указатель на передаваемое сообщение

int sbytes, // размер передаваемого сообщения

void *rmsg, //указатель на буфер для ответного сообщения

int rbytes //размер ответного сообщения

);

//отправка сообщения серверу

if(MsgSend(cid, smsg, strlen(smsg)+1, rmsg, sizeof(rmsg)) == -1){

печать сообщение об ошибке отправки сообщения серверу; return;

}

if(strlen (rmsg) > 0){

printf("Process c ID %i beantwortet: %s\n", pid, rmsg);

}

 

}

Функция сервера для приема сообщений от клиентов

int MsgReceive(int chid,//идентификатор канала

void *rmsg,//указатель на принимаемое сообщение

int rbytes,//размер сообщения

struct msg_info *info

);

Для ответа клиенту сервер использует функцию MsgReply().

int MsgReply(int rcvid, //идентификатор отправителя

int status,//значение анализируется клиентом

const void *msg,//указатель на отправляемое сообщение

int nbytes //размер сообщения

);

Рассмотрим соотношение параметров между функциями MsgSend(), MsgReceive() и MsgReply(), рис.2.3.2.

Рис.2.3.2. Соотношение параметров между функциями MsgSend(), MsgReceive() и MsgReply()

Клиент вызывает функцию MsgSend() и указывает ей на буфер передачи (указатель smsg и длина буфера sbytes). Данные передаются в буфер функции MsgReceive() на стороне сервера, по адресу rmsg и длиной буфера rbytes. Клиент блокируется.

Функция MsgReceive() сервера разблокируется и возвращает идентификатор отправителя rcvid, который будет использован впоследствии для ответа клиенту. Теперь сервер может использовать полученные от клиента данные.

Сервер завершил обработку сообщения и теперь использует идентификатор отправителя rcvid, полученный от функции MsgReceive(), передавая его функции MsgReply(). Данные для передачи клиенту задаются в функции MsgReply через указатель на буфер – smsg и размер – sbytes. Ядро передает данные клиенту.

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

Задание 9

Цель работы —для приведенного выше примера клиента написать периодическую отправку сообщений серверу через интервал времени равный 1сек.


Дата добавления: 2015-12-08; просмотров: 38 | Нарушение авторских прав



mybiblioteka.su - 2015-2024 год. (0.008 сек.)