消息隊列是一個存放在內(nèi)核中的消息鏈表,每個消息隊列由隊列標(biāo)識符標(biāo)識,與管道不同的是消息隊列是放在內(nèi)核當(dāng)中,只有在內(nèi)核重啟,或者顯式的刪除一個消息隊列,該消息隊列才會被真正的刪除,以下會有幾個操作,
1.創(chuàng)建消息隊列
#include
#include
key_t ftok(const char* pathname,int proj_id);
根據(jù)傳入的參數(shù)的唯一性,創(chuàng)建一個消息隊列
int? msgget(key_t key,int msgflag);
該參數(shù)ley是即為ftok函數(shù)的返回值,mshflag是一個標(biāo)識參數(shù)
IPC_CREATE:如果內(nèi)核中不存在于key相等的消息隊列,則新建一個消息隊列
IPC_EXCL和IPC_CREATE一起使用,如果對應(yīng)鍵值的消息對流已經(jīng)存在,則出錯,返回-1
2.寫消息隊列
int msgsnd(int msgid,struct msgbuf* msgp,size_t msgz,int msgflag)
msgid是消息隊列的標(biāo)識
msgp是發(fā)送的消息
msgz要發(fā)送的消息的大小
msgflag操作標(biāo)識,當(dāng)他是0的時候,當(dāng)消息隊列已曼則,msgsnd則會阻塞,直到可以寫入,如果msgflag是
IPC_NOWAIT的時候,如果消息隊列已滿則,立即返回
3.讀消息隊列
int msgrcv(int msgid,struct msgbuf* msgp,size_t msglen,long msgtyp,int msgflag);
現(xiàn)在源代碼如下
msg_server.c
/* ?*?main.cpp ?* ?*??Created?on:?Jul?18,?2014 ?*??????Author:?john ?*/ #include#include#include#include#include#include#include#include#include#include#include#define?BUF_SIZE?256 #define?PROJ_ID??32 #define?PATH_NAME?"/tmp" #define?SERVER_MSG??1 #define?CLIENT_MSG?2 using?namespace?std; int?main() { ???struct?mymsg ???{ ?????long?msgtype; ?????char?content[256]; ???}msgbuf; ??? ??//?var?define ???int?qid;//消息隊列標(biāo)識 ????int?msglen;//消息長度 ???key_t?msgkey; ? ??//獲取鍵值 ??msgkey=ftok(PATH_NAME,PROJ_ID); ??if(msgkey==-1) ???{ ?????cout<<"sorry?key?create?failed:?"<<strerror(errno)<<endl; ?????exit(0);??? ??} ??//獲取消息隊列 ??cout<<"創(chuàng)建鍵值成功n"; ?? ??qid=msgget(msgkey,IPC_CREAT|0666); ??if(qid==-1) ???{ ??????cout<<"get?msg?quen?failed?"<<strerror(errno)<<endl; ??????exit(0); ???} ??cout<<"獲取消息隊列成功"<<qid<<"n"; ??//開始讀取和寫入消息 ??while(1) ??{ ?????cout<>msgbuf.content; ?????if(strncmp(msgbuf.content,"exit",4)==0) ?????{ ???? ?//獲取消息屬性,IPC——RMID從內(nèi)核中刪除qid的消息隊列 ?????????msgctl(qid,IPC_RMID,NULL); ?????????exit(0); ?????} ?????msgbuf.msgtype=SERVER_MSG; ??????if(?msgsnd(qid,&msgbuf,strlen(msgbuf.content)+1,0)==-1) ?????{ ??????????cout<<"msg?send?failed"<<endl; ??????????exit(1); ?????} ??????cout<<"正在接收客戶端的消息n"; ?????if(msgrcv(qid,&msgbuf,BUF_SIZE,CLIENT_MSG,0)==-1) ?????{ ?????????cout<<"msg?rcv?failed"<<endl; ?????????exit(0); ?????} ?????cout<<"Client:?"<<msgbuf.content<<endl; ????? ??} }
msg_client.c文件如下:
/* ?*?main.cpp ?* ?*??Created?on:?Jul?18,?2014 ?*??????Author:?john ?*/ #include#include#include#include#include#include#include#include#include#include#include#define?BUF_SIZE?256 #define?PROJ_ID??32 #define?PATH_NAME?"/tmp" #define?SERVER_MSG??1 #define?CLIENT_MSG?2 using?namespace?std; int?main() { ???struct?mymsg ???{ ?????long?msgtype; ?????char?content[256]; ???}msgbuf; ??//?var?define ???int?qid;//消息隊列標(biāo)識 ????int?msglen;//消息長度 ???key_t?msgkey; ??//獲取鍵值 ??msgkey=ftok(PATH_NAME,PROJ_ID); ??if(msgkey==-1) ???{ ?????cout<<"sorry?key?create?failed:?"<<strerror(errno)<<endl; ?????exit(0); ??} ??cout<<"獲取鍵值成功n"; ??//獲取消息隊列 ??qid=msgget(msgkey,IPC_CREAT|0666); ??if(qid==-1) ???{ ??????cout<<"get?msg?quen?failed?"<<strerror(errno)<<endl; ??????exit(0); ???} ??cout<<"獲取消息隊列成功"<<qid<<"n"; ??//開始讀取和寫入消息 ??while(1) ??{ ??cout<<"正在接收服務(wù)器給客戶段的消息n"; ??if(msgrcv(qid,&msgbuf,BUF_SIZE,SERVER_MSG,0)==-1) ??????{ ??????????cout<<"msg?rcv?failed"<<endl; ??????????exit(0); ??????} ??????cout<<"Server:?"<<msgbuf.content<<endl; ?????cout<>msgbuf.content; ?????if(strncmp(msgbuf.content,"exit",4)==0) ?????{ ???? ?//獲取消息屬性,IPC——RMID從內(nèi)核中刪除qid的消息隊列 ?????????msgctl(qid,IPC_RMID,NULL); ?????????exit(0); ?????} ?????msgbuf.msgtype=CLIENT_MSG; ??????if(?msgsnd(qid,&msgbuf,strlen(msgbuf.content)+1,0)==-1) ?????{ ??????????cout<<"msg?send?failed"<<endl; ??????????exit(1); ?????} ??} }
唯一需要注意的是,在msgrcv的參數(shù)中要寫入需要接收的消息的類型。