精华内容
下载资源
问答
  • linux消息队列通信

    千次阅读 2012-04-25 23:19:38
    程序目的:学习linux消息队列通信 所用主要函数:msgget(),msgsnd(),msgrcv(),msgctl() 首先介绍每个函数的用法: (1)msgget 使用格式: #include #include #include int msgget(key_t k e y, int f l...

    程序目的:学习linux消息队列通信

    所用主要函数:msgget(),msgsnd(),msgrcv(),msgctl()

    首先介绍每个函数的用法:

    (1)msgget

    使用格式:
    #include <sys/types.h>  
    #include <sys/ipc.h>   
    #include <sys/msg.h>
    int msgget(key_t k e y, int  f l a g) ;

    功能:是打开一个现存队列或创建一个新队列。

    返回值:成功执行时,返回消息队列标识值。失败返回-1,有时也会返回0,这个时候也是可以正常使用的。

    参数key:消息队列关联的键,可以直接赋值设为固定的的键值。也可以用ftok()。

    也介绍一下ftok函数key_t ftok( char * fname, int id )

    fname就是你指定的文件名(已经存在的文件名),一般使用当前目录;id是子序号。

    这样就能得到一个固定的key_t值。

    参数f l a g:消息队列的建立标志和存取权限,建立标志一般为指定为IPC_CREAT和IPC_EXCL标志 。

    IPC_CREAT:如果内核中没有此队列,则创建它。当IPC_CREAT和IPC_EXCL一起使用时,如果队列已经存在,则失败。

    例:msgget(ftok("./file",123),IPC_CREAT |0666)

    (2)msgsnd

    功能:在消息队列上进行收发消息。为了发送消息,调用进程对消息队列必须有写权能。接收消息时必须有读权能。
    使用格式:
    #include <sys/types.h>  
    #include <sys/ipc.h>   
    #include <sys/msg.h>
    int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
    返回值:成功执行时,返回消息队列标识值。失败返回-1。
    参数:
    msqid:消息队列的识别码。
    msgp:指向消息缓冲区的指针,此位置用来暂时存储发送和接收的消息,是一个用户可定义的通用结构,如下
    struct msgbuf {   
       long mtype; //消息类型,必须 大于0   
     char mtext[1]; // 消息文本   
    };
    msgsz:消息的大小。  
    msgflg:用来指明核心程序在队列没有数据的情况下所应采取的行动。当msgflg为IPC_NOWAIT不会阻塞。当msgflg为0时msgsnd()在队列呈满或呈空的情形时,采取阻塞等待的处理模式。
    (3)msgrcv
    使用格式:
    #include <sys/types.h>  
    #include <sys/ipc.h>   
    #include <sys/msg.h>
    ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
    参数:(同上2)
    msgtyp:消息类型
    其他参数同上(2)。
    (4)msgctl
    原型: int msgctl ( int msgqid, int cmd, struct msqid_ds *buf );
    返回值: 如果成功为0 错误返回- 1。
    参数msgqid :是消息队列对象的标识符。
    第二个参数cmd:是函数要对消息队列进行的操作,它可以是:
     IPC_STAT取出系统保存的消息队列的msqid_ds 数据,并将其存入参数buf 指向的msqid_ds 结构
     中。
     IPC_SET设定消息队列的msqid_ds 数据中的msg_perm 成员。设定的值由buf 指向的msqid_ds
     结构给出。
     IPC_EMID将队列从系统内核中删除。
     这三个命令的功能都是明显的。唯一需要强调的是在IPC_STAT
     命令中队列的msqid_ds 数据中唯一能被设定的只有msg_perm 成员,是ipc_perm 类型的
     数据。而ipc_perm 中能被修改的只有mode,pid 和uid 成员。其他的都是只能由系统来设定
     的。
    ******************************有关范例*********************************************
    下面就看一个用消息队列通信写的一个简单的银行取号小程序:
    在这里我用到了两个进程:msgc.c  和 msg.c
    (1)msg.c
    #include<stdio.h>
    #include<stdlib.h>
    #include<sys/ipc.h>
    #include<sys/msg.h>
    #include<string.h>
    #define MSG_KEY 8888
    struct mymesg{
     long mtype;//消息类型
     char mtext[512];//消息内容

    };
    int main(void)
    {
     int msgid;
     struct msqid_ds buf;
     struct mymesg mymsg;
     msgid=msgget(MSG_KEY,IPC_CREAT |0600);//创建一个新队列
     if(-1==msgid)
     {
      perror("msggit");
      exit(EXIT_FAILURE);
     }
     while(1)
     {
      printf("请输入号码和内容:\n");
      scanf("%d %s",&mymsg.mtype,mymsg.mtext); 
      msgsnd(msgid,&mymsg,strlen(mymsg.mtext)+1,0);//发送mymsg中的信息到msgid对应的消息队列
     }
     return 0;
    }
    (2)msg.c
    #include<stdio.h>
    #include<stdlib.h>
    #include<sys/ipc.h>
    #include<sys/msg.h>
    #include<string.h>
    #define MSG_KEY 8888
    struct mymesg{
     long mtype;
     char mtext[512];
    };
    int main(void)
    {
     int msgid;
     struct mymesg mymsgrcv;
     msgid=msgget(MSG_KEY,IPC_CREAT |0600);
     if(-1==msgid)
     {
      perror("msggit");
      exit(EXIT_FAILURE);
     }
     while(1)
     { 
                                 printf("请选择号码:");
      scanf("%d",&mymsgrcv.mtype);
      int ms=msgrcv(msgid,&mymsgrcv,512,mymsgrcv.mtype,0);//接收消息队列相应类型(号码)信息
      if(-1==ms)
      {
       perror("msgrcv");
       exit(EXIT_FAILURE);
      }
      printf("received:%s\n",mymsgrcv.mtext);
             }
      int msg=msgctl(msgid,IPC_RMID,0);//将队列从系统内核中删除。
      if(-1==msg)
      {
       perror("msgctl");
       exit(EXIT_FAILURE);
      }
     
     return 0;
    }
    /*********************程序运行结果*********************
    [root@localhost msg]#gcc -o msg.c msg.c
    [root@localhost msg]# ./msg.c第一个进程
    请输入号码和内容:
    1  Personal business
    请输入号码和内容:
    2   company business
    请输入号码和内容:
    3   Other business
    [root@localhost msg]# gcc -o msgc.c msgc.c
    [root@localhost msg]# ./msgc.c第二个进程
    请选择号码:1
    received:Personal business
    请选择号码:2
    received:company business
    ……
    ***********************************************************/
    本人初学者,在写本博文中可能有一些不当的地方,欢迎大家向我指正。

    展开全文
  • linux消息队列linux消息队列linux消息队列linux消息队列linux消息队列进程间通信进程间通信
  • 主要介绍了Linux消息队列实现进程间通信实例详解的相关资料,需要的朋友可以参考下
  • Linux下系统通过进程消息队列进行通信。重庆大学操作系统实验2
  • linux 消息队列实现通信

    千次阅读 2016-10-27 08:36:03
    一、什么是消息队列 消息队列提供了一种从一个进程向另一个进程发送一个数据块的方法。 每个数据块都被认为含有一个类型,接收进程可以独立地接收含有不同类型的数据结构。我们可以通过发送消息来避免命名管道的同步...
    一、什么是消息队列
    消息队列提供了一种从一个进程向另一个进程发送一个数据块的方法。  每个数据块都被认为含有一个类型,接收进程可以独立地接收含有不同类型的数据结构。我们可以通过发送消息来避免命名管道的同步和阻塞问题。但是消息队列与命名管道一样,每个数据块都有一个最大长度的限制。

    消息队列的最佳定义是:内核地址空间中的内部链表。消息可以顺序地发送到队列中,并以几种不同的方式从队列中获取。当然,每个消息队列都是由 IPC标识符所唯一标识的。


    二、消息队列的创建

    #include <sys/types.h>
       #include <sys/ipc.h>
       #include <sys/msg.h>
       int msgget(key_t key, int msgflg)

    key:键值,由ftok获得。
       msgflg:标志位。

      IPC_CREAT如果在内核中不存在该队列,则创建它。

      IPC_EXCL当与IPC_CREAT一起使用时,如果队列早已存在则将出错。


    返回值:与健值key相对应的消息队列描述字


    三、读写消息队列

    include <sys/msg.h>

    int msgsnd ( int msqid, const void *prt, size_t nbytes, int flags);

    对于写入队列的每一个消息,都含有三个值,正长整型的类型字段、数据长度字段和实际数据字节。新的消息总是放在队列的尾部,函数中参数msqid指定要操作的队列,ptr指针指向一个msgbuf的结构,定义如下:

    struct msgbuf{

        long mtype;

        char mbuf[];

    };

    这是一个模板的消息结构,其中成员 mbuf是一个字符数组,长度是根据具体的消息来决定的,切忌消息不能以NULL结尾。成员mtype是消息的类型字段。

    函数参数nbytes指定了消息的长度,参数flags指明函数的行为。函数成功返回0,失败返回–1并设置错误变量errnoerrno可能出现的值有:EAGAINEACCESEFAULTEIDRMEINTREINVALENOMEM。当函数成功返回后会更新相应队列的msqid_ds结构。

    使用函数msgrcv可以从队列中读取消息,函数原型如下:


    #include <sys/msg.h>

    ssize_t msgrcv ( int msqid, void *ptr, size_t nbytes, long type , int flag);

    函数中参数msqid为指定要读的队列,参数ptr为要接收数据的缓冲区,nbytes为要接收数据的长度,当队列中满足条件的消息长度大于nbytes的值时,则会参照行为参数flag的值决定如何操作:当flag中设置了MSG_NOERROR位时,则将消息截短到nbytes指定的长度后返回。如没有MSG_NOERROR位,则函数出错返回,并设置错误变量errno。设置type参数指定msgrcv函数所要读取的消息,tyre的取值及相应操作如表所示。

    type值详解

    等于0

    返回队列最上面的消息(根据先进先出规则)

        

    大于0

    返回消息类型与type相等的第1条消息

        

    小于0

    返回消息类型小于等于type绝对值的最小值的第1条消息

        

    参数flag定义函数的行为,如设置了IPC_NOWAIT位,则当队列中无符合条件的消息时,函数出错返回,errno的值为ENOMSG。如没有设置IPC_NOWAIT位,则进程阻塞直到出现满足条件的消息出现为止,然后函数读取消息返回。

    下面实例演示了消息队列在进程间的通信。程序中创建了一个消息的模板结构体,并对声明变量做初始化。使用 msgget 函数创建了一个消息队列,使用 msgsnd 函数向该队列中发送了一条消息。


    四、消息队列的控制

    该函数用来控制消息队列,它与共享内存的shmctl函数相似,它的原型为:

    int msgctl(int msgid, int command, struct msgid_ds *buf); 

    ommand是将要采取的动作,它可以取3个值,

        IPC_STAT:把msgid_ds结构中的数据设置为消息队列的当前关联值,即用消息队列的当前关联值覆盖msgid_ds的值。
        IPC_SET:如果进程有足够的权限,就把消息列队的当前关联值设置为msgid_ds结构中给出的值
        IPC_RMID:删除消息队列


    五、实例

    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <errno.h>
    #include <unistd.h>
    
    #include <sys/types.h>
    #include <sys/ipc.h>
    #include <sys/msg.h>
    
    struct my_msg_st
    {
        long int my_msg_type;
    	char some_text[BUFSIZ];
    };
    
    int main(void)
    {
        int running=1;
    	int msgid;
    	struct my_msg_st some_data;
    	long int msg_to_receive=0;
    
    	/*创建消息队列*/
    	msgid=msgget((key_t)1234,0666 | IPC_CREAT);
    	if(msgid==-1)
    	{
    	    fprintf(stderr,"msgget failed with error: %d\n",errno);
    		exit(EXIT_FAILURE);
    	}
    	
    	/*循环从消息队列中接收消息*/
    	while(running)
    	{
    		/*读取消息*/
    	    if(msgrcv(msgid,(void *)&some_data,BUFSIZ,msg_to_receive,0)==-1)
    		{
    		    fprintf(stderr,"msgrcv failed with error: %d\n",errno);
    			exit(EXIT_FAILURE);
    		}
    
    		printf("You wrote: %s",some_data.some_text);
    
    		/*接收到的消息为“end”时结束循环*/
    		if(strncmp(some_data.some_text,"end",3)==0)
    		{
    		    running=0;
    		}
    	}
    
    	/*从系统内核中移走消息队列*/
    	if(msgctl(msgid,IPC_RMID,0)==-1)
    	{
    	    fprintf(stderr,"msgctl(IPC_RMID) failed\n");
    		exit(EXIT_FAILURE);
    	}
    	exit(EXIT_SUCCESS);
    }
    
    

    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <errno.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/ipc.h>
    #include <sys/msg.h>
    #define MAX_TEXT 512
    
    struct my_msg_st
    {
        long int my_msg_type;
    	char some_text[MAX_TEXT];
    };
    
    int main(void)
    {
        int running=1;
    	struct my_msg_st some_data;
    	int msgid;
    	char buffer[BUFSIZ];
    
    	/*创建消息队列*/
    	msgid=msgget((key_t)1234,0666 | IPC_CREAT);
    	if(msgid==-1)
    	{
    	    fprintf(stderr,"msgget failed with error:%d\n",errno);
    		exit(EXIT_FAILURE);
        }
    
    	/*循环向消息队列中添加消息*/
    	while(running)
    	{
    	    printf("Enter some text:");
    		fgets(buffer,BUFSIZ,stdin);
    		some_data.my_msg_type=1;
    		strcpy(some_data.some_text,buffer);
    
    		/*添加消息*/
    		if(msgsnd(msgid,(void *)&some_data,MAX_TEXT,0)==-1)
    		{
    		    fprintf(stderr,"msgsed failed\n");
    			exit(EXIT_FAILURE);
    		}
    
    		/*用户输入的为“end”时结束循环*/
    		if(strncmp(buffer,"end",3)==0)
    		{
    		    running=0;
    		}
    	}
    	exit(EXIT_SUCCESS);
    }
    





    展开全文
  • linux消息队列进程通信 一、消息队列的基本概念 消息队列 (也叫做报文队列)是Unix系统V版本中3种进程间通信机制之一。另外两种是信号灯和共享内存。这些IPC机制使用共同的授权方法。只有通过系统调用将...

    http://www.cnblogs.com/magicbox/archive/2012/02/01/2363880.html

    linux消息队列进程通信

    一、消息队列的基本概念

    消息队列 (也叫做报文队列)是Unix系统V版本中3种进程间通信机制之一。另外两种是信号灯和共享内存。这些IPC机制使用共同的授权方法。只有通过系统调用将标志符传递给核心之后,进程才能存取这些资源。这种系统IPC对象使用的控制方法和文件系统非常类似。使用对象的引用标志符作为资源表中的索引。

    消息队列就是一个消息的链表。就是把消息看作一个记录,并且这个记录具有特定的格式以及特定的优先级。对消息队列有写权限的进程可以按照一定的规则添加新消息;对消息队列有读权限的进程则可以从消息队列中读出消息。

    Linux采用消息队列的方式来实现消息传递。这种消息的发送方式是:发送方不必等待接收方检查它所收到的消息就可以继续工作下去,而接收方如果没有收到消息也不需等待。这种通信机制相对简单,但是应用程序使用起来就需要使用相对复杂的方式来应付了。新的消息总是放在队列的末尾,接收的时候并不总是从头来接收,可以从中间来接收。

    消息队列是随内核持续的并和进程相关,只有在内核重起或者显示删除一个消息队列时,该消息队列才会真正被删除。因此系统中记录消息队列的数据结构 (struct ipc_ids msg_ids)位于内核中,系统中的所有消息队列都可以在结构msg_ids中中找到访问入口。

    IPC标识符:每一个I P C目标都有一个唯一的I P C标识符。这里所指的I P C目标是指一个单独的消息队列、一个信号量集或者一个共享的内存段。系统内核使用此标识符在系统内核中指明 I P C目标。

    IPC 关键字:想要获得唯一的标识符,则必须使用一个 I P C关键字。客户端进程和服务器端进程必须双方都同意此关键字。这是建立一个客户机/服务器框架的第一步。在System V IPC机制中,建立两端联系的路由方法是和I P C关键字直接相关的。通过在应用程序中设置关键字值,每一次使用的关键字都可以是相同的。一般情况下,可以使用f t o k ( )函数为客户端和服务器端产生关键字值。

    二、ipcs 命令

    命令ipcs用于读取System V IPC目标的状态。
    ipcs -q: 只显示消息队列。
    ipcs -s: 只显示信号量。
    ipcs -m: 只显示共享内存。
    ipcs –help: 其他的参数。

    三、消息队列的主要调用

    内核中实现消息传递机制的代码基本上都在文件ipc/msg.c中,消息队列的主要调用有下面4个

    (1)msgget:调用者提供一个消息队列的键标 (用于表示个消息队列的唯一名字),当这个消息队列存在的时候, 这个消息调用负责返回这个队列的标识号;如果这个队列不存在,就创建一个消息队列,然后返回这个消息队列的标识号 ,主要由sys_msgget执行。

    (2)msgsnd:向一个消息队列发送一个消息,主要由sys_msgsnd执行。

    (3)msgrcv:从一个消息队列中收到一个消息,主要由sys_msgrcv执行。

    (4)msgctl:在消息队列上执行指定的操作。根据参数的不同和权限的不同,可以执行检索、删除等的操作,主要由sys_msgctl执行。



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

    int msgget( key_t msgkey , int flag );
    取得一个消息队列的ID,如不存在则建立。
    返回值: 成功时:消息队列的ID
    失败时:-1



    int msgsnd( int msqid , struct msgbuf *msgp , size_t msgsiz , int msgflag );
    向消息队列送消息
    返回值: 成功时:0
    失败时:-1
    msqid是消息队列的ID,size_t msgsiz是结构体成员mdata的大小,msgflag与上一章所讲的共享内存的flag起一样的作用,不过,当这个参数为IPC_NOWAIT的时候,如果消息队列已满,则返回错误值。如果不为IPC_NOWAIT,在消息队列已满 的情况下,会一直等到消息队列有空地方的时候再发送。
    注意这里的这个 struct msgbuf *msgp 。要求的格式如下:
    struct msgbuf
    {
    long mtype;
    char mdata[256];
    };
    long mtype在这里我们用来保存本进程的PID。mdata则是保存要发送的数据。由于mdata的大小不一定(根据实际需要定义),所以这个结构体并没有事先定义好。但是我们定义这个结构体的时候一定要遵循这个规定。你可以改的,只有mdata的大小,和结构体的名称。尽量不要修改结构体成员的名称和类型。实际上,根据mtype,我们还可以有所选择地接受消息。这在下面将会谈到。




    int msgrcv( int msqid , struct msgbuf *msgp , size_t msgsiz , long msgtyp , int msgflag );
    从消息队列取得一个消息
    返回值: 成功时:0
    失败时:-1
    msqid , *msgp , msgsiz不用说了。long msgtyp是结构体msgbuf的mtype成员。msgflag与上述一样。只不过为IPC_NOWAIT的时候,如果消息队列是空的,则等到有消息可读的时候再读。当不为IPC_NOWAIT的时候,如果消息队列是空的,则返回错误值(与字面上理解的有些相反)


    下面这个链接帮助了我更好地理解了msgrcv 中的 long msgtyp这个参数和

    struct msgbuf
    {
    long mtype;
    char mdata[256];
    };

    里的long mtype这个结构体成员。

    http://topic.csdn.net/u/20120131/15/235be4a4-3901-41ef-a577-55a5650efeeb.html?14521



    同样地,为了控制管理消息队列,一样有一个函数msgctl()如下:
    #include <sys/types.h>
    #include <sys/ipc.h>
    #include <sys/msg.h>

    int msgctl( int msqid , int cmd , struct msqid_ds *buf );
    返回值: 成功时:0
    失败时:-1
    cmd所指定的值与共享内存部分相同。


    最后自己写了一个利用消息队列实现进程通信

    基本思路:

    我每次将A端发送消息时的消息类型标记为奇数,将B端发送的消息类型为偶数。

    A端读取消息类型为偶数的消息(也就是说是从B端发送过来的)

    B端读取消息类型为奇数的消息(也就是说是从A端发送过来的)


    A.c和B.c 程序基本上是一样的

    这个程序还有一些不完善的地方:

    1.每个端口不能连续输入,必须等对方输入以后才 会显示结果。这里我也不清楚怎么回事。gdb的调试还不太会,错误不太会找。希望高手指教,呵呵

    2.没有删除消息队列,下次打开时候还会残留以前的消息


    最后列出参考资料:

    http://linux.chinaunix.net/techdoc/develop/2009/04/27/1109110.shtml

    http://blog.sina.com.cn/s/blog_48c9576b0100joqg.html

    http://blog.sina.com.cn/s/blog_48c9576b0100joqg.html

    《Linux软件工程师(c语言)实用版》

    展开全文
  • linux消息队列测试

    2018-08-28 08:08:19
    linux消息队列实现进程间通信的测试程序,包括发送程序和接收程序,想消息队列推送一条消息以及从消息发送到队列再到接受端程序读出消息,大概只有3-5微秒的时间。
  • 关于Linux系统进程通信的概念及实现可查看:http://www.ibm.com/developerworks/cn/linux/l-ipc/   关于Linux系统消息队列的概念及实现可查看:http://www.ibm.com/developerworks/cn/linux/l-ipc/part4/   PHP...
  • Linux消息队列实现进程间通信

    千次阅读 2017-06-02 23:58:53
    什么是消息队列消息队列提供了从一个进程向另一个进程发送一个有类型数据块的方法。用这种方法可以避免命名管道的同步和阻塞问题。消息队列是基于消息的,而管道是基于字节流的,并且消息队列的读取不一定是先入...
     
    
    什么是消息队列:
    消息队列提供了从一个进程向另一个进程发送一个有类型数据块的方法。用这种方法可以避免命名管道的同步和阻塞问题。消息队列是基于消息的,而管道是基于字节流的,并且消息队列的读取不一定是先入先出。

    消息队列的操作:
    消息队列的创建或者获取:
    int msgget(key_t key, int msgflg);
    参数描述:
    key:是一个端口号,可以由ftok()生成
    msgflg:  IPC_CREAT:如果IPC不存在,则创建,存在就打开
                    IPC_EXECL:单独使用无太大意义,与IPC_CREAT一块使用代表,IPC不存在创建,存在出错,返回
    key_t ftok(const char *pathname, int proj_id);
    生成唯一一个key供用户使用,返回一个消息队列标识符。
    返回值:
    成功返回消息队列的id,失败返回-1。
    读取消息:
    ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
    参数描述:
    msgid:消息队列的标识符
    msgp:指向一个缓冲区的指针,用来暂时存放储存发送和接受的消息,是一个用户可以定义的通用结构。
    struct msgstru{
        long mtype; //大于0
        char mtext;//用户指定大小
    };
    msgz:消息的大小
    msgtyp:从消息队列中读取的消息形态
    msgflg:用来指明核心程序在队列没有数据的情况下所应采取的行动。如果msgflg和常 数IPC_NOWAIT合用,则在msgsnd()执行时若是消息队列已满,则msgsnd()将不会阻塞,而 会立即返回-1,如果执⾏行的是msgrcv(),则在消息队列呈空时,不做等待马上返回-1,并设定 错误码为ENOMSG。当msgflg为0时,msgsnd()及msgrcv()在队列呈满或呈空的情形时,采取 阻塞等待的处理模式。
    返回值:
    成功返回实际读取到的字节数,失败返回-1。
    发送消息:
    int msgsnd(int msqid, const void *msgp, size_t msgz, int msgflg);
    参数与读取消息函数的参数相同。
    返回值;
    成功返回0,失败返回-1。

    消息队列的查看:
    可以使用 ipcs -q 来查看系统中的消息队列;
    可以使用ipcrm -q +消息队列id  来删除对应id的消息队列

    消息队列的实例:
    实现一个server和一个client程序,他们之间利用消息队列进行通信。
    comm.h
    #ifndef  _COMM_H_
    #define  _COMM_H_
    #ifndef  _COMM_H_
    #define  _COMM_H_
    
    #include<stdio.h>
    #include<sys/types.h>
    #include<sys/ipc.h>
    #include<sys/msg.h>
    #include<string.h>
    
    #define PATHNAME "."
    #define PROJ_ID 0x666
    
    #define SERVER_TYPE 1
    #define CLIENT_TYPE 2
    
    //自定义一个缓冲区用来暂时存储发送或者接收的数据
    struct msgbuf
    {
        long mytype;
        char mtext[1024];
    };
    int createMsgQueue();
    int getMsgQueue();
    int destroyMsgQueue(int msgid);
    int sendMsg(int msgid, int type, char *msg);
    int recvMsg(int msgid, int recvType, char out[]);
    #endif
    

    comm.c
    #include "comm.h"
    
    //创建或者打开消息队列
    static int commMsgQueue(int flag)
    {
        key_t key = ftok(PATHNAME, PROJ_ID);
        if(key < 0)
        {
        perror("ftok");
        return -1;
        }
        //根据flag的不同选择打开还是创建
        int msgid = msgget(key, flag);
        if(msgid < 0)
        {
        perror("msgget");
        return -2;
        }
        return msgid;
    }
    int createMsgQueue()
    {
        return commMsgQueue(IPC_CREAT|IPC_EXCL|0666);
    }
    int getMsgQueue()
    {
        return commMsgQueue(IPC_CREAT);
    }
    int destroyMsgQueue(int msgid)
    {
        //删除消息队列
        if(msgctl(msgid, IPC_RMID, NULL)<0)
        {
        perror("msgctl");
        return -1;
        }
        return 0;
    }
    //发送消息(参数:发送者,发送内容的类型,发送的内容)
    int sendMsg(int msgid, int who, char *msg)
    {
        //buf 自定义的缓冲区,用来暂存数据
        struct msgbuf buf;
        buf.mytype = who;
        strcpy(buf.mtext, msg);
        //进行发送,将缓冲区中的数据进行发送
        if(msgsnd(msgid, (void *)&buf, sizeof(buf.mtext), 0) < 0)
        {
        perror("msgsnd");
        return -1;
        }
        return 0;
    }
    //接收消息(参数:接受者,接受类型,接受之后存放位置)
    int recvMsg(int msgid, int who, char out[])
    {
        struct msgbuf buf;
        buf.mytype = who;
        //接收数据,将接收的数据写入到缓冲区中
        if(msgrcv(msgid, (void *)&buf, sizeof(buf.mtext), recvType, 0)< 0)
        {
        perror("msgrcv");
        return -1;
        }
        //将数据从缓冲区存放到指定位置
        strcpy(out, buf.mtext);
        return 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));
        if(s > 0)
        {
            buf[s-1] = 0;
            //将缓冲区内容发送至客户端
            sendMsg(msgid, SERVER_TYPE, buf);
            printf("send done...\n");
        }
        }
        //服务器端创建,服务器端销毁消息队列
        destoryMsgQueue(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));
        if(s>0)
        {
            buf[s-1] = 0;
            //将缓冲发送到服务器
            sendMsg(msgid, CLIENT_TYPE, buf);
            printf("send done...\n");
        }
        //接受服务器的回应
        recvMsg(msgid, SERVER_TYPE, buf);
        printf("Server : %s\n", buf);
    
        }
       return 0;
    }
    

    运行结果:


    展开全文
  • Linux消息队列

    2013-03-21 17:00:57
    Linux消息队列 ---------学习linux下 c编程之消息队列
  • 消息队列是一种以链表为结构组织的数据,存放在Linux内核中,是由各进程通过消息队列标识符来引用的一种数据传送方式。每个消息队列都有一个队列头,利用结构struct msg_queue来描述。队列头中包含了该消息队列的...
  • 一、消息队列的特点  1.消息队列消息的链表,具有特定的格式,存放在内存中并由消息队列标识符标识.  2.消息队列允许一个或多个进程向它写入与读取消息.  3.管道和命名管道都是通信数据都是先进先出的原则。...
  • linux消息队列进行通信的 简单示例代码
  • 3)利用Linux消息队列通信机制实现两个线程间的通信 编写程序创建三个线程:sender1线程、sender2线程和receiver线程,三个线程的功能描述如下: ①sender1线程:运行函数sender1(),它创建一个消息队列,然后...
  • 实现linux两不同进程用消息队列通信 还不错 !
  • linux 进程通信-消息队列详解,详细阐述了linux或者unix下面的进程通过消息队列通信
  • linux消息队列源码

    2014-03-27 21:54:25
    Linux下通过消息队列机制实现双方通信
  • Linux消息队列进程通信的介绍

    千次阅读 2012-02-03 10:42:44
    一、消息队列的基本概念消息队列 (也叫做报文队列)是Unix系统V版本中3种进程间通信机制之一。另外两种是信号灯和共享内存。这些IPC机制使用共同的授权方法。只有通过系统调用将标志符传递给核心之后,进程才能存取...
  • linux消息队列实现进程间通信

    千次阅读 2017-06-07 22:22:30
    常用的进程间通信的方式有两种:通过管道和systemv标准,今天我们来介绍systemv标准中的一种:消息队列 消息队列消息队列提供了一种从一个进程向另一个进程发送一个数据块的方法,每个数据块都认为是有一个类型,...
  • Linux进程间通信——消息队列

    千次阅读 2018-04-24 11:07:45
    一、什么是消息队列 消息队列提供了一种从一个进程向另一个进程发送一个数据块的方法。 每个数据块都被认为含有一个类型,... Linux用宏MSGMAX和MSGMNB来限制一条消息的最大长度和一个队列的最大长度。 二、在Li...
  • Linux消息队列完成进程间通信

    千次阅读 2012-07-12 10:54:54
    消息队列(message queue)是Linux系统进程间通信的一种方式。  关于Linux系统进程通信的概念及实现可查看:http://www.ibm.com/developerworks/cn/linux/l-ipc/  关于Linux系统消息队列的概念及实现可查看...
  • 前几天在计算机操作系统课中学习了Linux下进程通信,今日做了个消息队列通信的简单小程序,权当练习。  程序有服务器和客户端两个进程。先运行服务器,然后客户端。客户端向服务器发送问题,服务器收到后可进行...
  • SystemV消息队列是OpenGroup定义的XSI,不属于POSIX标准。SystemVIPC的历史相对很早,在上个世70年代后期有贝尔实验室的分支机构开发,80年代加入...系统内核都会为每一个SystemV消息队列维护一个信息结构,在Linux
  • Linux进程通信消息队列

    千次阅读 2020-11-08 14:17:30
    Linux进程通信消息队列 消息队列主要由下面四个函数组成   1、msgget   2、msgctl   3、msgsnd   3、msgrcv 1、msgget 得到消息队列标识符或创建一个消息队列对象并返回消息队列标识符 函数原型 #...
  • Linux进程间通信——使用消息队列

    万次阅读 多人点赞 2013-08-25 00:09:57
    下面来说说如何用不用消息队列来进行进程间的通信消息队列与命名管道有很多相似之处。 一、什么是消息队列 消息队列提供了一种从一个进程向另一个进程发送一个数据块的方法。 每个数据块都被认为含有一个类型,...
  • 利用PHP操作Linux消息队列完成...消息队列(message queue)是Linux系统进程间通信的一种方式。  关于Linux系统进程通信的概念及实现可查看:http://www.ibm.com/developerworks/cn/linux/l-ipc/  关于Linux
  • Linux消息队列编程(简单应用)

    万次阅读 多人点赞 2018-08-15 23:35:51
    消息队列,Unix的通信机制之一,可以理解为是一个存放消息(数据)容器。将消息写入消息队列,然后再从消息队列中取消息,一般来说是先进先出的顺序。可以解决两个进程的读写速度不同(处理数据速度不同),系统耦合...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 106,396
精华内容 42,558
关键字:

linux消息队列通信

linux 订阅