客户端与服务端通信(Server&Client)的消息队列实现

消息队列

    提供从一个进程向另一哥进程发送一块数据的方法
    每个数据块都被认为有一个类型,接收者进程收到的数据块可以有不同类型值
    消息队列的最大长度,总字节数,消息队列的数都有上限

comm.h

#pragma once
#include<stdio.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<string.h>

#define PATHNAME "."
#define PROJ_ID 0X6666

#define SERVER_TYPE 1
#define CLIENT_TYPE 2

struct msgbuf{   //消息结构
    long mtype;
    char mtext[1024];
};

int createMsgQueue();  //创建消息队列函数
int getMsgQueue();       //访问消息队列函数
int destroyMsgQueue(int msgid); //销毁消息队列函数
int sendMsg(int msgid, int who ,char *msg); //发送消息
int recvMsg(int msgid, int recvType, char out[]);  //接受消息

comm.c

#include"comm.h"
static int commMsgQueue(int flags)   //控制消息队列函数
{
    key_t _key=ftok(PATHNAME,PROJ_ID);   //创建消息队列获取ID
    if(_key<0)       
    {
        perror("ftok");   //获取ID失败
        return -1 ;
    }
    int msgid=msgget(_key,flags);//创建和访问一个消息队列
    //int msgid=msgget(_key,IPC_CREAT|IPC_EXCL);
    if(msgid<0)   
    {
        perror("msgget");  //创建或者访问失败
    }
    return msgid ;  //创建成功返回标识码
}

int createMsgQueue()     //创建消息队列函数
{
    return commMsgQueue(IPC_CREAT|IPC_EXCL|0666); //调整队列权限
}

int getMsgQueue()  //访问消息队列
{
    return commMsgQueue(IPC_CREAT);
}

int destroyMsgQueue(int msgid)  //销毁消息队列函数
{
    int m=msgctl(msgid,IPC_RMID,NULL) ;  //删除消息队列
    if(m<0)
    {
        perror("msgctl");   //删除失败
        return -1 ;
    }
    //删除成功
    return 0;       
}

int sendMsg(int msgid, int who ,char*msg)  //发送消息
{
    struct msgbuf buf ;
    buf.mtype=who;
    strcpy(buf.mtext,msg);  //把消息拷贝到buf.mtext中

    if(msgsnd(msgid,(void*)&buf,sizeof(buf.mtext),0)<0)
    {
        perror("msgsnd");   //发送失败
        return -1;
    }
    //发送成功
    return  0;
}

int recvMsg(int msgid, int recvType ,char out[]) //接收消息
{
    struct msgbuf buf ;
    if(msgrecv(msgid,(void*)&buf,sizeof(buf.mtext), recvType ,0)<0)
    {  //接收失败
        perror("msgrecv");
        return -1 ;
    }
    //接收成功
    strcpy(out,buf.mtext);  拷贝消息内容到outreturn 0 ;
}

服务端server.c

#include"comm.h"
int main()
{
    int msgid=createMsgQueue(); //创建消息队列

    char buf[1024];    
    while(1)
    {
        buf[0]=0;
        recvMsg(msgid,CLIENT_TYPE,buf);  //接收消息
        printf("client# %s\n",buf);    //打印接收到的消息

        printf("Please enter# ");
        fflush(stdout);   //刷新
        ssize_t s=read(0,buf,sizeof(buf)); //从当前读取信息到buf中
        if(s>0)    //读取成功
        {
            buf[s-1]=0;
            sendMsg(msgid,SERVER_TYPE,buf);  //服务器发送消息
            printf("send done,wait recv...\n");
        }
    }
    destroyMsgQueue(msgid);   //调用销毁消息队列函数
    return 0;
}

客户端client.c

#include"comm.h"
int main()
{
    int msgid=getMsgQueue();  //创建消息队列

    char buf[1024];
    while(1)
    {
        buf[0]=0;
        printf("please enter# ");  
        fflush(stdout);    //刷新
        ssize_t s=read(0,buf,sizeof(buf));  //把内容读取到buf中
        if(s>0)
        {    //读取成功
            buf[s-1]=0;
            sendMsg(msgid,CLIENT_TYPE,buf); //客户端发送消息到buf中
            printf("send  done ,wait recv...\n"); 

        }
        recvMsg(msgid,SERVER_TYPE,buf);//接收服务端发来的消息到buf中
        printf("server# %s\n",buf);   //打印收到的消息
    }
    return 0 ; 
}

这里写图片描述
这里写图片描述

猜你喜欢

转载自blog.csdn.net/yu876876/article/details/80328055