进程间的通信之消息队列

消息队列

  • 本质:内核中提供的一种链表,提供了一个进程向另一个进程发送一块数据块的方法
  • 消息队列的常见函数以及解析,参考以下这个博主的博客,有相关的总结
    -https://blog.csdn.net/xiaohuima_dong/article/details/44773815

  • 用消息队列实现进程间的通信

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

    char buf[1024];    
    while(1)
    {
        buf[0]=0;
        recvMsg(msgid,CLIENT_TYPE,buf);  //接收消息,来自客户端的,到buf中
        printf("client# %s\n",buf);    //打印存放在buf中收到的数据

        printf("Please enter# ");      //服务器准备向客户端发送数据
        fflush(stdout);   
        ssize_t s=read(0,buf,sizeof(buf)); //从当前(0表示当前)读取数据到buf中
        if(s>0)    //读取成功
        {
            buf[s-1]=0;
            sendMsg(msgid,SERVER_TYPE,buf);  //将数据发送         
            printf("send done,wait recv...\n");
        }
    }
    destroyMsgQueue(msgid);   
    return 0;
}



//客户端
#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 ; 
}



//函数的实现
#include"comm.h"
static int commMsgQueue(int flags)   //控制消息队列函数
{
    key_t _key=ftok(PATHNAME,PROJ_ID);   //获取消息队列的名字,也就是ID
    if(_key<0)       
    {
        perror("ftok");   
        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);  拷贝消息内容到out中
    return 0 ;
}


//头文件
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[]);  //接受消息
  • 消息队列用于任意进程之间,全双工通信

  • 面向数据报(无论报文多长不拆分不合并,一次发送一个)

  • 生命周期随内核:直到显示删除
@localhost ~]$ ipcrm -q 32768

如图,执行命令后就会不见

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值