Message Queuing ---- bidirectional communication (read not necessarily first-in, first-out)
1. Message Queuing provides a way to send a block of data from one process to another. Each data block is recognized
To be a type, the recipient process receives a block of data that can have different type values. We can send messages by
To avoid synchronization and blocking problems with Named pipes.
Message Queuing differs from a pipeline in that Message Queuing is message-based , and the pipeline is based on a byte stream , and the read of Message Queuing is not necessarily first-in-first-out.
2. Structure of message queue:
struct ipc_perm { key_t _key; /* key supplied to xxxget (2) */ uid_t uid; /* Effective UID of owner */ gid_t gid; /* effective GID of owner */ uid_t cuid; /* effective uid of creator */ gid_t cgid; /* effective gid of creator */ unsigned short mode; /* permissions */ unsigned short _seq; /* Sequence number */};
3, the implementation of Message Queuing:
Header file:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
--------------------------------------------------------------------
(1) Create a new message queue or get a message queue that already exists
int Msgget (key_t key, int msgflg);//Create a new message queue or get an existing message queue
Key: Can be thought of as a port number, or it can be generated by the function Ftok ().
MSGFLG:
Ipc_creat If the IPC does not exist, create an IPC resource, or open the operation.
IPC_EXCL: The new shared memory is established only if the shared memory does not exist, or an error occurs.
(2) Read/write messages to the queue
ssize_t MSGRCV (int msqid, void *msgp, size_t msgsz, long Msgtyp, int msgflg);//read message from queue int msgsnd (int msqid, const void *MS GP, size_t msgsz, int msgflg);//write data to the message queue
MSGFLG: Indicates the action that the core program should take if the queue has no data.
If the MSGFLG and constant ipc_nowait are pooled, then: 1. If the message queue is full at msgsnd () execution, msgsnd () will not block and will return to -1;2 immediately. If you are performing a MSGRCV (), when the message queue is empty, Do not wait to return immediately-1, and set the error code to enomsg.
When MSGFLG is 0 o'clock, msgsnd () and MSGRCV () when the queue is full or empty, take
The processing mode of blocking waits.
(3) Setting Message Queuing properties
int msgctl (int msgqid, int cmd, struct msqid_ds *buf);//Set Message Queuing properties
cmd operation : Ipc_stat, Ipc_set, Ipc_rmid
Ipc_stat : Gets the MSQID_DS data structure corresponding to the message queue and saves it to the address space specified by BUF.
Ipc_set : Sets the properties of the message queue, and the properties to be set are stored in BUF.
ipc_rmid : Removes the MSQID identity message queue from the kernel.
4. Example: Client server bidirectional communication
Comm.h
#ifndef _msg_#define _msg_#include<stdio.h> #include <stdlib.h> #include <unistd.h> #include < string.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #include <errno.h > #define _PATH_ "." #define _PROC_ID_ 0x6666#define _client_id_ 1#define _server_id_ 2#define _block_size_ 256struct msg_buf{long Mtype;char Mtext[_block_size_];}; int comm_msg_queue (int flag); int create_msg_queue (); int get_msg_queue (); int msg_send (int msg_id,int _mtype,const char * _info); int msg_recv (int msg_id,int Recv_type,char buf[]); int destroy_msg_queue (int msg_id); #endif
Comm.c
#include "comm.h" Int comm_msg_queue (int flag) {Key_t _key=ftok (_path_,_proc_id_); if (_key < 0) {perror ("Ftok"); return -1;} Int msg_id=msgget (_key,flag); if (msg_id < 0) {perror ("Msgget"); return -1;} return msg_id;} Int create_msg_queue () {int flag = (ipc_creat | ipc_excl |0666); //0666 :set permission return comm_msg_queue (flag);} Int get_msg_queue () {int flag = ipc_creat;return comm_msg_queue (flag);} Int msg_send (int msg_id,int _mtype,const char *_info) {struct msg_buf _msg;_ Msg.mtype=_mtype;memset ((void*) _msg.mtype, ' strcpy ', sizeof (_msg.mtype)) (_msg.mtext,_info); if (Msgsnd (msg_id), &_msg,sizeof (_msg.mtext), ipc_nowait) < 0)//non-blocking wait{perror ("msgsnd"); return -1;} return 0;} INT&NBSP;MSG_RECV (int msg_id,int recv_type,char buf[]) {struct msg_buf _msg;if (MSGRCV ( Msg_id,&_msg,sizeof (_msg.mtext), recv_type,0) < 0)//blocking wait{perror ("MSGRCV"); return -1;} strcpy (buf,_msg.mtext); return 0;} Int destroy_msg_queue (int msg_id) {if (Msgctl (msg_id,ipc_rmid,null) < 0)//release{perror ( "Msgctl"); return -1;} else{printf ("remove msg queue done ...\n");} return 0;}
Server.c
#include "comm.h" int main () {int queue_id=create_msg_queue (); if (queue_id < 0) {perror ("Create_msg_queue"); exit (1);} Char Buf[_block_size_];while (1) {memset (buf, ' n ', sizeof (BUF)); Msg_recv (QUEUE_ID,_CLIENT_ID_,BUF);//server Receives info from clientprintf ("Client #%s\n", buf);p rintf ("Please Enter:"); Fflush (stdout); Fgets (Buf,sizeof (BUF), stdin); Msg_send (QUEUE_ID,_SERVER_ID_,BUF);//server sends info to Client}destroy_msg_queue (queue_id); return 0;}
Client.c
#include "comm.h" int main () {int queue_id=get_msg_queue (); if (queue_id < 0) {perror ("Get_msg_queue"); exit (1);} Char Buf[_block_size_];while (1) {printf ("Please Enter:");//input Infofflush (stdout); Fgets (Buf,sizeof (BUF), stdin); Msg_send (QUEUE_ID,_CLIENT_ID_,BUF);//client sends info to SERVERMSG_RECV (QUEUE_ID,_SERVER_ID_,BUF);//client Receives info from serverprintf ("Server #%s\n", buf);} Destroy_msg_queue (queue_id); return 0;}
This article is from the "Flower Open Shore" blog, please be sure to keep this source http://zxtong.blog.51cto.com/10697148/1763901
Implementation of Message Queuing