Message Queuing
Message Queuing provides a way to send a block of data from one process to another. each block of data is considered to contain a type, and the receiving process can independently receive data structures that contain different types. You can avoid synchronization and blocking problems for named pipes by sending messages. But Message Queuing, like named Pipes, has a maximum length limit for each block of data. Linux uses macro Msgmax and MSGMNB to limit the maximum length of a message and the maximum length of a queue.
msgget functionThis function is used to create and access a message queue.
int int
key: Like other IPC mechanisms, a program must provide a key to name a particular message queue.
MSGFLG: is a permission flag that represents the access rights for Message Queuing, which is the same as access to a file. MSGFLG can be done or manipulated with ipc_creat, which means that when a message queue named by key is not present, a message queue is created, and if a message queue named by key is present, the IPC_CREAT flag is ignored and only one identifier is returned. it returns an identifier for a message queue named key (nonzero integer), which returns -1 on failure.
msgsnd functionThis function is used to add messages to the message queue. Its prototype is:
int msgsend (intconstvoidint msgflg);
MsgId: is the message queue identifier returned by the Msgget function.
msg_ptr: is a pointer to prepare to send a message, but the data structure of the message has certain requirements, the pointer msg_ptr the message structure must be a long integer member variable start structure, the receive function will use this member to determine the type of message. MSG_SZ: Is the length of the message that msg_ptr points to, not the length of the
entire struct, that is, the length of the member variable that MSG_SZ does not include the long integer message type.
MSGFLG: Used to control what will happen when the current message queue is full or the queue message reaches the system-wide limit. The message structure is defined like this:
struct my_message{ longint message_type; /* The data wish to transfer */ };
If the call succeeds, a single copy of the message data is placed in the message queue and returns 0, returning -1 on failure.
MSGRCV functionThis function is used to get messages from a message queue
int MSGRCV (intvoidlongintint
MsgId, Msg_ptr, Msg_st functions as function msgsnd functions.
Msgtype: A simple receive priority can be achieved. If Msgtype is 0, it gets the first message in the queue. If its value is greater than 0, it gets the first information with the same message type. If it is less than 0, it gets the first message with a type equal to or less than the absolute value of Msgtype.
MSGFLG: Used to control what happens when there are no corresponding types of messages in the queue that can be received. when the call succeeds, the function returns the number of bytes placed in the receive buffer, the message is copied to the user-allocated buffer that is pointed to by msg_ptr, and the corresponding message in the message queue is deleted. Returns -1 upon failure.
msgctl functionThis function is used to control Message Queuing, which is similar to the SHMCTL function of shared memory
int msgctl (intintstruct
Command: Is the action that will be taken, it can take 3 values,Ipc_stat: Sets the data in the MSGID_DS structure to the current associated value of the message queue, which overwrites the value of Msgid_ds with the current association value of the message queue. Ipc_set: If the process has sufficient permissions, set the current association value for the message queue to the value given in the MSGID_DS structureipc_rmid: Deleting Message Queuing
buf: is a pointer to the MSGID_DS structure that points to the Message Queuing pattern and the structure of the access permission. the MSGID_DS structure includes at least the following members:
struct Msgid_ds { uid_t shm_perm.uid; uid_t Shm_perm.gid; mode_t Shm_perm.mode;
returns 0 on success and -1 on failure.
Example
Receive information:
#include <unistd.h>#include<stdlib.h>#include<stdio.h>#include<string.h>#include<errno.h>#include<sys/msg.h>structMsg_st {Long intMsg_type; CharText[bufsiz]; }; intMain () {intrunning =1; intMsgId =-1; structMsg_st data; Long intMsgtype =0;//Note 1//Establish Message QueuingMsgId = Msgget ((key_t)1234,0666|ipc_creat); if(MsgId = =-1) {fprintf (stderr,"Msgget failed with error:%d\n", errno); Exit (Exit_failure); } //gets the message from the queue until the end message is encountered while(running) {if(Msgrcv (MsgId, (void*) &data, Bufsiz, Msgtype,0) == -1) {fprintf (stderr,"MSGRCV failed with errno:%d\n", errno); Exit (Exit_failure); } printf ("You wrote:%s\n", Data.text); //Meet End if(STRNCMP (Data.text,"End",3) ==0) Running=0; } //Delete Message Queuing if(Msgctl (MsgId, Ipc_rmid,0) == -1) {fprintf (stderr,"Msgctl (ipc_rmid) failed\n"); Exit (Exit_failure); } exit (exit_success); }
Send message:
#include <unistd.h>#include<stdlib.h>#include<stdio.h>#include<string.h>#include<sys/msg.h>#include<errno.h>#defineMax_text 512structMsg_st {Long intMsg_type; CharText[max_text]; }; intMain () {intrunning =1; structMsg_st data; CharBuffer[bufsiz]; intMsgId =-1; //Establish Message QueuingMsgId = Msgget ((key_t)1234,0666|ipc_creat); if(MsgId = =-1) {fprintf (stderr,"Msgget failed with error:%d\n", errno); Exit (Exit_failure); } //writes a message to the message queue until the end is written to while(running) {//input Dataprintf"Enter some text:"); Fgets (buffer, bufsiz, stdin); Data.msg_type=1;//NOTE 2strcpy (data.text, buffer); //sending data to a queue if(Msgsnd (MsgId, (void*) &data, Max_text,0) == -1) {fprintf (stderr,"msgsnd failed\n"); Exit (Exit_failure); } //input end End input if(STRNCMP (Buffer,"End",3) ==0) Running=0; Sleep (1); } exit (exit_success); } Results:
? JIANGTF ./Sendenter Some text:absyou wrote:absenter some text:tjdfyou wrote:tjdfenter some text:endyou wrote: end[1] 59241 done ./a . Out
Message Type detailsNote the variable Msgtype in the Receive file (note 1), which acts as the value of the receive information type parameter of the MSGRCV function, with a value of 0, that is the first available message in the Get queue. Take a look at the statement in the while loop in the Send file Data.msg_type = 1 (note 2), which is used to set the type of information that is sent, that is, the type of information it sends is 1. So the program msgreceive can receive the information sent by the program Msgsend. If you take note 1, that is, long int msgtype = 0, change to long int msgtype = 2;msgreceive will not be able to receive the information sent by the program Msgsend. Because when the MSGRCV function is called, if Msgtype (the fourth argument) is greater than 0, only the first message with the same message type is obtained, the modified message type is 2, and Msgsend sends a message type of 1, so it cannot be received by the Msgreceive program. Recompile the msgreceive.c file and execute it again, with the following results:
? JIANGTF ./Sendenter Some text:asdenter some text:intadenter some text:end
Differences between Message Queuing and named pipes
In a named pipe, send data with write, receive data with read, then in message queue, send data with MSGSND, receive data with MSGRCV. And they have a maximum length limit for each data. The advantage of Message Queuing compared to named Pipes is that:
1. Message Queuing can also exist independently of the send and receive processes, eliminating the difficulties that can arise when synchronizing the opening and closing of named pipes.
2. By sending messages, you can also avoid the synchronization and blocking problems of named pipes, and do not need to provide synchronization methods by the process itself.
3. The receiving program can selectively receive data through the message type, instead of being received only by default, as in a named pipe.
Reference: http://www.cnblogs.com/lidabo/p/4323807.html
Network communication--Message Queuing