訊息佇列的通訊原理及建立訊息佇列程式設計收發資料
阿新 • • 發佈:2020-12-19
技術標籤:linux
1.訊息佇列,是訊息的連結表,存放在核心中,一個訊息佇列由一個識別符號(即佇列ID)來標識。
2.特點:
- 訊息佇列是面向記錄的,其中的訊息具有特定的格式以及特定的優先順序
- 訊息佇列獨立於傳送與接收程序。程序終止時,訊息佇列及其內容並不會被刪除
- 訊息佇列可以實現訊息的隨機查詢,訊息不一定要以先進先出的次序讀取,也可以按訊息的型別讀取
3.訊息佇列相關api
<1> int msgget(key_t key, int flag);
功能:開啟或建立訊息佇列。
返回值:成功返回佇列ID,失敗返回-1
引數說明:
- key:訊息佇列的鍵值,多個程序可以通過它訪問同一個訊息佇列,可通過ftok函式來獲取。其中有個特殊值IPC_PRIVATE,用於建立當前程序的私有訊息佇列。在以下兩種情況下,msgget將建立一個新的訊息佇列:1)如果沒有與鍵值key相對應的訊息佇列,並且flag中包含了IPC_CREAT標誌位;2)key引數為IPC_PRIVATE
- flag:許可權標誌位
*<2> int msgsnd(int msqid, const void ptr, size_t size, int flag);
功能:新增訊息
返回值:成功返回0,失敗返回-1
引數說明:
-
msqid:訊息佇列的佇列ID
-
ptr:指向訊息結構的指標,該訊息結構msgbuf通常如下:
struct msgbuf { long mtype; // 訊息型別,該結構必須從這個域開始 char mtext[1]; // 訊息正文 }
-
size:訊息正文的位元組數(不包含訊息型別指標變數)
-
flag:1)IPC_NOWAIT:若訊息無法立即傳送(如當前訊息佇列已滿),函式會立即返回0。msgsnd呼叫直到傳送成功為止;2)0:忽略標誌位
*<3> int msgrcv(int msqid, void ptr, size_t size, long type,int flag);
功能:讀取訊息
返回值:成功返回訊息資料的長度,失敗返回-1
引數說明:
- msqid:訊息佇列的佇列ID
- ptr:訊息緩衝區,同msgsnd函式的ptr
- size:訊息正文的位元組數
- type:有三種情況:1)等於0:接收訊息佇列中第一個訊息;2)大於0:接收訊息佇列中第一個型別為type的訊息;3)小於0:接收訊息佇列中第一個型別值不小於type絕對值且型別值最小的訊息
- flag:1)MSG_NOERROR:若返回的訊息比size位元組多,則訊息就會截短到size位元組,且不通知訊息傳送程序;2)IPC_NOWAIT:若在訊息佇列中並沒有相應型別的訊息可以接收,則函式立即返回;3)0:msgsnd函式呼叫阻塞直到接收一條相應型別的訊息為止
*<4> int msgctl(int msqid, int cmd, struct msqid_ds buf);
功能:控制訊息佇列
返回值:成功返回0,失敗返回-1
引數說明:
- msqid:訊息佇列的佇列ID
- cmd:命令引數,有三個可供選擇:1)IPC_STAT:讀取訊息佇列的資料結構msqid_ds,並將其儲存在buf指定的地址中;2)IPC_SET:設定訊息佇列的資料結構msqid_ds中的ipc_perm域(IPC操作許可權描述結構)值,這個值取自buf引數;3)IPC_RMID:從系統核心中刪除訊息佇列
- buf:描述訊息佇列的msqid_ds結構型別變數(也可以為NULL)
4.demo:
// 獲取訊息端
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
struct msgbuf
{
long mtype;
char mtext[128];
};
int main()
{
struct msgbuf readBuf;
key_t key;
key = ftok(".",'z'); // 獲取msgget函式裡的key值
printf("key = %x\n",key);
int msgId = msgget(key,IPC_CREAT|0777); // 建立訊息佇列,記得要加許可權,成功返回佇列ID
if(msgId == -1){
printf("get Que failed\n");
}
msgrcv(msgId,&readBuf,sizeof(readBuf.mtext),888,0); // 讀取訊息
printf("read from que:%s\n",readBuf.mtext);
struct msgbuf sendBuf = {988,"thank you for reach"};
msgsnd(msgId,&sendBuf,strlen(sendBuf.mtext),0); // 傳送訊息
msgctl(msgId,IPC_RMID,NULL); // 刪除訊息佇列
return 0;
}
// 傳送訊息端
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
struct msgbuf
{
long mtype;
char mtext[128];
};
int main()
{
struct msgbuf sendBuf = {888,"this is message from quen"};
struct msgbuf readBuf;
key_t key;
key = ftok(".",'z');
printf("key = %x\n",key);
int msgId = msgget(key,IPC_CREAT|0777);
if(msgId == -1){
printf("get Que failed\n");
}
msgsnd(msgId,&sendBuf,strlen(sendBuf.mtext),0);
printf("send Over\n");
msgrcv(msgId,&readBuf,sizeof(readBuf.mtext),988,0);
printf("return from get:%s\n",readBuf.mtext);
msgctl(msgId,IPC_RMID,NULL);
return 0;
}
執行結果: