linux笔记之消息队列

来源:互联网 发布:淘宝主图尺寸750 编辑:程序博客网 时间:2024/06/01 07:58

一.IPC主题之消息队列

  • 消息队列:一个进程向另一个进程提供有类型数据块的模板。
  • 数据块:例如 一边发一百个字节的数据块,则另一边接收一百个字节的数据块,少了任何一部分,这一块都是无效的。而流是写多少读多少,传的数据无明显的格式要求。
  • 内核为每个IPC对象维护一个数据结构
struct ipc_prem()//围绕着消息队列的权限问题的源信息{...};
  • 每一个IPC特有一个数据结构
struct msgid_ds{//用来描述队列的信息,可以用它来设置 获取 调整操作系统内部消息队列源信息...}

二.用代码实现消息队列

1.创建消息队列
所用到的函数:
这里写图片描述
2.获取消息队列
所用到的函数和创建所用到的一样。
3.发送消息队列
所用到的函数如下图:
这里写图片描述
4.接收消息
所用到的函数:
这里写图片描述
5.销毁消息队列
所用到的函数:
这里写图片描述

三.源代码

  • comm.h
#ifndef __COMM_H__#define __COMM_H__#include<stdio.h>#include<sys/msg.h>#include<sys/types.h>#include<sys/ipc.h>#include<errno.h>#include<string.h>#define SERVER_TYPE 1#define CLIENT_TYPE 2#define PATHNAME "."#define PROJ_ID 0x6666#define SIZE 128struct msgbuf {    long mtype;       /* message type, must be > 0 */    char mtext[SIZE];    /* message data */ };int CreatmesQueue();int GetmesQueue();int SentmesQueue(int mspid,long type,const char* _info);int ReceivermesQueue(int msgid,long type,char out[]);int DestorymesQueue(int mspid);#endif
  • comm.c
#include"comm.h"int comm_que(int msflg){    int key=ftok( PATHNAME,PROJ_ID);    if(key<0)    {        perror("ftok");        return -1;    }    int mspid=msgget(key,msflg);    if(mspid<0)    {        perror("mesget");        return -2;    }    return mspid;}int CreatmesQueue(){    return comm_que(IPC_CREAT|IPC_EXCL|0666);} int GetmesQueue() {    return comm_que(IPC_CREAT); } int SentmesQueue(int mspid,long type,const char* _info){    struct msgbuf buf;    buf.mtype=type;    strcpy(buf.mtext,_info);    if(msgsnd(mspid,&buf,sizeof(buf.mtext),0)<0)    {        perror("msgsnd");        return -1;    }    return 0;}int ReceivermesQueue(int msgid,long type,char out[]){    struct msgbuf buf;    if(msgrcv(msgid,&buf,sizeof(buf.mtext),type,0)<0)    {        perror("msgrcv");        return -1;    }    strcpy(out,buf.mtext);    return 0;}int DestorymesQueue(int mspid){    if(msgctl(mspid,IPC_RMID,NULL)<0)    {        perror("msgctl");        return -1;    }}
  • server.c
#include"comm.h"int main(){    int msgid=CreatmesQueue();    char out[SIZE];    while(1)//receive->send    {        ReceivermesQueue(msgid,CLIENT_TYPE,out);        printf("client>%s\n",out);        printf("Please enter $:");        fflush(stdout);        ssize_t s=read(0,out,sizeof(out)-1);        if(s > 0)        {            out[s-1]='\0';            SentmesQueue(msgid,SERVER_TYPE,out);        }    }    DestorymesQueue(msgid);    return  0;}
  • client.c
#include"comm.h"int main(){    int msgid=GetmesQueue();    char out[SIZE];    while(1)//sent->rece    {//send        printf("please enter $: ");        fflush(stdout);        ssize_t s=read(0,out,sizeof(out)-1);        if(s>0)        {            out[s-1]='\0';            SentmesQueue(msgid,CLIENT_TYPE,out);        }        //rece        ReceivermesQueue(msgid,SERVER_TYPE,out);        printf("server >%s\n",out);    }    return  0;}
  • makefile.c
client_=clientserver_=servercc=gcccliSrc=client.c comm.cserSrc=server.c comm.c.PHONY:allall:$(client_) $(server_)$(client_):$(cliSrc)    $(cc) -o $@ $^$(server_):$(serSrc)    $(cc) -o $@ $^.PHONY:cleanclean:    rm -f $(client_) $(server_)

四.运行结果图

server.c运行结果图
这里写图片描述
client.c运行结果图
这里写图片描述

0 0