消息队列实现回射客户服务器

本章目标:

消息队列实现回射客户/服务器

模型框架如下:

服务器端代码:

#include<unistd.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>

#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<string.h>

#define MSGMAX 8192

#define ERR_EXIT(m) \
    do\
    { \
        perror(m);\
        exit(EXIT_FAILURE);\
    }while(0)

struct msgbuf
{
    long mtype;
    char mtext[MSGMAX];
};

void echo_srv(int msgid)
{
    int n;
    struct msgbuf msg;
    memset(&msg,0,sizeof(msg));
    while(1)
    {
        if((n = msgrcv(msgid,&msg,MSGMAX,1,0)) <0)
            ERR_EXIT("msgsnd");
        int pid;
        memcpy(&pid,msg.mtext,4);
        fputs(msg.mtext+4,stdout);
        //printf("%s\n",msg.mtext+4);
        msg.mtype = pid;
        msgsnd(msgid,&msg,n,0);
    }
    
}

int main(void)
{
    int msgid;
    //创建一个消息队列
    msgid = msgget(1234,0666|IPC_CREAT);
    if(msgid == -1)
        ERR_EXIT("msgget");
    
    echo_srv(msgid);//不停接收类型为1的类型
    return 0;
}

客户端代码:

#include<unistd.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>

#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<string.h>

#define MSGMAX 8192

#define ERR_EXIT(m) \
    do\
    { \
        perror(m);\
        exit(EXIT_FAILURE);\
    }while(0)

struct msgbuf
{
    long mtype;
    char mtext[MSGMAX];
};

void echo_cli(int msgid)
{
    int n;
    int pid;
    pid = (int)getpid();
    struct msgbuf msg;
    memset(&msg,0,sizeof(msg));
    memcpy(msg.mtext,&pid,4);
    
    //*((int*)msg.mtext) = pid;//将前四个字节保存pid  可以用memcpy函数
    msg.mtype = 1;  //客户端发送的数据类型为1
    //不停从键盘上获取一行数据
    while(fgets(msg.mtext+4,MSGMAX,stdin)!=NULL)
    {
        if((msgsnd(msgid,&msg,4+strlen(msg.mtext),0)) <0)
            ERR_EXIT("msgsnd");

        memset(msg.mtext+4,0,MSGMAX-4);

        if((n = msgrcv(msgid,&msg,MSGMAX,pid,0)) <0)
            ERR_EXIT("msgsnd");

        fputs(msg.mtext+4,stdout);
        memset(msg.mtext+4,0,MSGMAX-4);
    }
    
}

int main(void)
{
    int msgid;
    //打开一个消息队列
    msgid = msgget(1234,0);
    if(msgid == -1)
        ERR_EXIT("msgget");
    
    echo_cli(msgid);//不停接收类型为1的类型
    return 0;
}

 

调试了一晚上,还是有问题。

1.未能在服务器端输出显示。换成printf()就行,fputs就不行。。

2.客户端可以接受到回显数据  但是只能回显两个字节。。。。。

 

满头雾水。。。不说了

 

上面这个模型中是有缺陷的,有可能造成死锁。当多个客户端将消息队列填满时,就会 死锁。

 

改进的模型;

 

posted @ 2017-03-29 21:49  ren_zhg1992  阅读(138)  评论(0)    收藏  举报