I. Message Queuing Concept
Message queues provide a way to send a block of data from one process to another. Each data block is considered to have a type, and the data block received by the receiver process can have different type values. We can send messages to avoid synchronization and blocking of named pipes. The difference between message queue and pipeline is that message queue is based on message, while pipeline is based on byte stream, and message queue reading is not necessarily FIFO. Message queue has the same shortcoming as named pipeline, that is, the maximum length of each message is upper bound (MSGMAX), the total number of bytes of each message queue is upper bound (MSGMNB), and message queue on the system is upper bound. The total number of columns also has an upper limit (MSGMNI)
II. Characteristics of message queues
(1) Message queues are linked lists of messages, stored in memory in a specific format and identified by message queue identifiers.
(2) The lifecycle of message queues follows the kernel.
(3) Message queues are message-based.
(4) Message queue can realize two-way communication.
(5) Message queue allows one or more processes to write and read messages to it
Third, the interface of message queue
1. Create a new message queue or get an existing message queue
Description of parameters:
The first parameter key, which can be considered as a port number, can also be generated by the ftok function, which uniquely identifies the ipc resources, where the key is generated by the ftorm function call.
The second parameter msgflg has two flags. IPC_CREAT and IPC_EXCL, when IPC_CREAT is used alone, if IPC does not exist, create an IPC resource, if it exists, open and return. If IPC_CREAT and IPC_EXCL are pressed or used, XXXget() will return a new IPC identifier, and - 1 if the IPC already exists.
2. Read/write messages to queues
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
//Placing data in message queues
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
//Cancel interest from queue
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);
Parametric analysis:
msqid: Message Queue Identification Code (not explained)
msgp: A pointer to a message buffer that temporarily stores messages sent and received. It is a user-defined generic structure, as follows
struct msgstru
{
long mtype;//More than 0;
char mtext[User specified size];
}
msgsz: message size
msgtyp: The type of message used to identify who sent the message.
msgflg: Message receiving mode, blocking and non-blocking mode.
3. Setting message queue properties
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
Parametric interpretation:
msg system calls perform cmd operations on message queues identified by msgqid. The system defines three cmd operations: IPC_STAT, IPC_SET and IPC_RMID.
IPC_STAT: Used to obtain the corresponding msgqid_ds data structure of the message queue and save it in the address space specified by buf.
IPC_SET: Used to set attributes in message queues. The attributes to be set exist in buf
IPC_RMID: Remove the message queue identified by msgqid from the kernel.
4. Implementation of message queue code
comm.h
1 #ifndef __COMM__
2 #define __COMM__
3
4 #include <stdio.h>
5 #include <sys/ipc.h>
6 #include <sys/msg.h>
7 #include <sys/types.h>
8 #include <string.h>
9 #include <stdlib.h>
10
11 #define FILENAME "."
12 #define PROJ_ID 0x6666
13
14 #define SERVER_TYPE 1
15 #define CLIENT_TYPE 2
16 struct _msginfo
17 {
18 long mtype;
19 char mtext[1024];
20 };
21 int CreatMsgQuenu();//Create message queues
22 int GetMsgQuenu();//Get message queue
23 int DestroyMsgQueue(int msgid);//Destroy message queue
24 int SendMsg(int msgid,int type,const char* msg);//Send data to message queues
25 int RecvMsg(int msgid,int type,char* out);//Retrieving data from message queues
26 #endif
comm.c
1 #include "comm.h"
2 static int commMsgQueue(int flags)
3 {
4 key_t _key = ftok(FILENAME,PROJ_ID);
5 if (_key <0)
6 {
7 perror("ftok\n");
8 return -1;
9 }
10
11 int msgid = msgget(_key,flags);
12 if (msgid <0)
13 {
14 perror("msgget\n");
15 return -2;
16 }
17 return msgid;
18 }
19
20 int CreatMsgQueue()
45 }
46 strcpy(out,msginfo.mtext);
47 return 0;
48 }
49 int SendMsg(int msgid,int type,const char* msg)
50 {
51 struct _msginfo msginfo;
52 msginfo.mtype = type;
53 strcpy(msginfo.mtext,msg);
54 if (msgsnd(msgid,&msginfo,sizeof(msginfo.mtext),0)<0)
55 {
56 perror("msgsnd\n");
57 return -1;
58
59 }
60 return 0;
61 }
62
msg_server.c
#include "comm.h"
2
3 int main()
4 {
5 int msgid = CreatMsgQueue();
1 #include "comm.h"
2
3 int main()
4 {
5 int msgid = CreatMsgQueue();
6 char buf[1024];
7 while(1)
8 {
9 buf[0] = 0;
10 RecvMsg(msgid,CLIENT_TYPE,buf);
11 printf("client say#%s\n",buf);
12 printf("server enter#");
13 fflush(stdout);//Refresh the above sentence on the screen
14 ssize_t s = read(0,buf,sizeof(buf)-1);
15 if (s>0)
16 {
17 buf[s-1] = 0;
18 SendMsg(msgid,SERVER_TYPE,buf);
19 }
20 }
21 DestroyMsgQueue(msgid);
22 return 0;
23 }
msg_client.c
#include "comm.h"
2
3 int main()
4 {
5 int msgid = GetMsgQueue();
6 char buf[1024];
7 while(1)
8 {
9 buf[0] = 0;
10 printf("client enter#");
11 fflush(stdout);
12
13 ssize_t s = read(0,buf,sizeof(buf)-1);
14 if (s>0)
15 {
16 buf[s-1] = 0;
17 SendMsg(msgid,CLIENT_TYPE,buf);
18 }
19 RecvMsg(msgid,SERVER_TYPE,buf);
20 printf("server say# %s\n",buf);
21
22 }
23 return 0;
24 }
Operation results:
V. Relevant Directives
(1) View message queue ipcs-q msqid
(2) Delete the message queue ipcrm-q msqid of the system