Читайте также:
|
|
Создать три потока. Осуществить обработку сообщений поступающих от клиентов в виде: 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 | Нарушение авторских прав