zoukankan      html  css  js  c++  java
  • System V消息队列

    消息的基本属性

    System V的消息属性包含在一个msqid_ds的结构中

    struct msqid_ds{
        struct ipc_cerm msg_perm;  //读取权限, 0644, 0777
        struct *msg_first; //消息队列的第一条消息地址
        struct *msg_last; //消息队列的最后一条消息地址
        msglen_t msg_cbytes; //当前消息的长度
        msgnum_t msg_qnum; //消息队列中的消息总数
        msglen_t msg_qbytes; //一条消息的最大长度
        pid_t msg_lspid; //last sender进程ID
        pid_t msg_lrpid; //last receiver进程ID
        time_t msg_stime; //time of last msgsnd()
        time_t msg_rtime; //time of last msgrcv()
        time_t msg_ctime; //time of last msgctl()
    };
    

    消息格式:
    由一个结构组成,第一个long参数类型表示消息类型(怎么解读消息由用户自己定义与系统无关), 且其值必须大于0; 第二个为消息内容, 其长度和数据类型可自定义; 除第一个结构成员固定外, 其它成员的数量也可以自定义

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

    基本函数:

    #include <sys/ipc.h>
    key_t ftok(char *fname, int id);
     
    #include <sys/msg.h>
    int msgget(key_t key, int oflag);
    int msgsnd(int msgqid, const void *ptr, size_t length, int flag);
    ssize_t msgrcv(int msqid, void *ptr, size_t length, long type, int flag);
    int msgctl(int msqid, int cmd, struct msqid_ds *buff);
    

    ftok函数:用于生成一个唯一的key_t, fname为一个已存在的文件名, id取0-255之间的正整数. 实际是通过获取文件的i节点号再加上id形成唯一的key_t.
    msgget函数:key_t可以为IPC_PRIVATE生成随机数; oflag可以是0644|IPC_CREAT|IPC_EXCL的组合
    msgsnd函数:前三个参数同write函数, flag为0或IPC_NOWAIT设定是否等待
    msgrcv函数:前三个参数同read函数,flag参数同msgsnd
    type=0时按顺序取出第一条消息
    type>0时取出消息队列中type为其值的第一条消息
    type<0时取绝对值范围内type最小的第一条消息
    msgctl函数:
    cmd=IPC_RMID时,删除指定的msqid消息队列,第三个参数无意义
    cmd=IPC_SET时,用第三个参数来代替当前消息队列属性
    cmd=IPC_STAT,获取msqid消息队列的属性,通过第三个参数返回

    包裹函数

    vmqpack.h

    #ifndef _VMQPACK_H
    #define _VMQPACK_H
     
    #include "unpipc.h"
    #include <sys/types.h>
    #include <sys/msg.h>
     
    struct msgbuf{
        long mtype;
        char mtext[100];
    };
     
    key_t Ftok(char *fname,int id);
    int Msgget(key_t key,int oflag);
    void Msgsnd(int mqid,const void *ptr,size_t length, int flag);
    ssize_t Msgrcv(int msqid, void *ptr, size_t length, long type, int flag);
    void Msgctl(int msqid, int cmd, struct msqid_ds *buff);
     
    #endif
    

    vmqpack.c

    #include "vmqpack.h"
     
    key_t Ftok(char *fname,int id){
        key_t key=ftok(fname,id);
        if(key == -1)
            err_quit("ftok error");
        return key;
    }
    int Msgget(key_t key,int oflag){
        int mqid=msgget(key,oflag);
        if(mqid == -1)
            err_quit("msgget errror");
        return mqid;
    }
    void Msgsnd(int mqid, const void *ptr, size_t length, int flag){
        if(msgsnd(mqid,ptr,length,flag) == -1)
            err_quit("msgsnd error");
    }
    ssize_t Msgrcv(int msqid, void *ptr, size_t length, long type, int flag ){
        ssize_t n=msgrcv(msqid,ptr,length,type,flag);
        if(n == -1)
            err_quit("msgrcv error");
        return n;
    }
    void Msgctl(int msqid, int cmd, struct msqid_ds *buff){
        int ret=msgctl(msqid,cmd,buff);
        if(ret == -1)
            err_quit("msgctl error");
    }
    

    发送与接收

    send.c

    #include "vmqpack.h"
     
    int main(int argc, char *argv[]){
        int mqid;
        long type;
        struct msgbuf buf;
        if(argc != 3)
            err_quit("usage: send <pathname> <type>");
        type=atoi(argv[2]);
        mqid=Msgget(ftok(argv[1],0),0644|IPC_CREAT);
        buf.mtype=type;
        strncpy(buf.mtext,"hello, server",strlen("hello,server")+1);
        Msgsnd(mqid,&buf,sizeof(buf),0);
        exit(0);
    }
    

    recv.c

    #include "vmqpack.h"
    int main(int argc, char *argv[]){
        int c,flag,mqid;
        long type;
        ssize_t n;
        struct msgbuf buff;
        key_t key;
        type=flag=0;
        while((c=getopt(argc,argv,"nt:")) != -1){
            switch(c){
                case 'n':
                    flag |= IPC_NOWAIT;
                    break;
                case 't':
                    type=atol(optarg);
                    break;
            }
        }
        if(optind != argc -1)
            err_quit("usage: recv[-n] [-t type] <pathname>");
        key=Ftok(argv[optind],0);
        mqid=Msgget(key,0400);
        n=Msgrcv(mqid,&buff,sizeof(buff),type,flag);
        printf("read %d bytes, type=%ld
    ",n,buff.mtype);
        printf("msgdata: %s
    ",buff.mtext);
        Msgctl(mqid,IPC_RMID,NULL);
        exit(0);
    }
    
  • 相关阅读:
    LIKE谓词
    [C#网络编程系列]专题一:网络协议简介
    (zz)Sql Server 2005中的架构(Schema)、用户(User)、角色(Role)和登录(Login)(三)
    zz让你成功的九个心理定律
    zz给 VSTO 插件、文档传送参数
    重构笔记
    (zz)Sql Server 2005中的架构(Schema)、用户(User)、角色(Role)和登录(Login)(二)
    zzVSTO 先瘦身再发布:客户端配置文件
    zz将 VSTO 插件部署给所有用户
    (zz)Sql Server 2005中的架构(Schema)、用户(User)、角色(Role)和登录(Login)(一)
  • 原文地址:https://www.cnblogs.com/cfans1993/p/5789317.html
Copyright © 2011-2022 走看看