利用訊息佇列實現簡單聊天程式
阿新 • • 發佈:2018-11-11
本篇利用訊息佇列的特性實現簡單的聊天程式,msgsnd傳送資料,msgrcv接收資料來實現聊天功能,訊息佇列詳情。
資料接收端msgrcv
//這是一個以system V訊息佇列實現的聊天程式客戶端 //// 1.建立訊息佇列 //// 2.從訊息佇列中獲取一個數據,打印出來 //// 3.從標準輸入中獲取一個數據,組織成訊息佇列節點發送 //// 4.刪除訊息佇列 //// 介面: //// 建立 msgget //// 接收資料 msgrcv //// 傳送資料 msgsnd //// 控制 msgctl //// int msgget(key_t key,int msgflg); //// msgflg: //// key:核心中訊息佇列的標識 //// IPC_CREAT 不存在則建立,存在則開啟 //// IPC_EXCL 與IPC_CREAT 同用,若存在則報錯 防止程式重複啟動 //// mod 許可權 //// 返回值:一個程式碼操作的控制代碼:失敗:-1 //// ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, //// int msgflg); //// msgid:msgget返回的操作控制代碼 //// smgp:用於接收資料 //// msgsz:指定接收的資料大小 //// msgtyp:指定接收的資料型別 //// msgflg:標準選項,0 #include<stdio.h> #include<unistd.h> #include<stdlib.h> #include<string.h> #include<errno.h> #include<sys/ipc.h> #include<sys/msg.h> #define IPC_KEY 0x12345678 //下面兩個巨集,用於我們賦值我們傳輸的資料塊型別 #define TYPE_S 1 #define TYPE_C 2 struct msgbuf { long mtype; /* message type, must be > 0 */ char mtext[1024]; /* message data */ }; int main() { int msgid=-1; //ftok // //key_t ftok(const char *pathname, int proj_id); // //ftok通過檔案的inode節點號和一個proj_id計算出一個key值 // //缺點:如果檔案被刪除,或者替換,那麼將開啟的不是同一個訊息佇列 // //1.建立訊息佇列 msgid=msgget(IPC_KEY,IPC_CREAT | 0664); if(msgid<0){ perror("msgget error"); return -1; } while(1){ //2.接收資料 //struct msgbuf這個結構體需要我們自己定義 struct msgbuf buf; //msgrcv:預設阻塞的獲取資料 //msgid:操作控制代碼 // //buf:接收資料的結構體,自己定義 //1024 用於指定接收的資料的最大長度,不包含mtype //TYPE_C 用於指定接收的資料型別 //msgflag 0預設 // MSG_NOERROR 當資料長度超過指定長度,則截斷資料 msgrcv(msgid,&buf,1024,TYPE_C,0); printf("client say:%s\n",buf.mtext); //傳送資料 memset(&buf,0x00,sizeof(struct msgbuf)); buf.mtype=TYPE_S; scanf("%s",buf.mtext); msgsnd(msgid,&buf,1024,0); } msgctl(msgid,IPC_RMID,NULL); return 0; }
資料傳送端msgsnd
#include<stdio.h> #include<unistd.h> #include<stdlib.h> #include<string.h> #include<errno.h> #include<sys/ipc.h> #include<sys/msg.h> #define IPC_KEY 0x12345678 //下面兩個巨集,用於我們賦值我們傳輸的資料塊型別 #define TYPE_S 1 #define TYPE_C 2 struct msgbuf { long mtype; /* message type, must be > 0 */ char mtext[1024]; /* message data */ }; int main() { int msgid=-1; //ftok // //key_t ftok(const char *pathname, int proj_id); // //ftok通過檔案的inode節點號和一個proj_id計算出一個key值 // //缺點:如果檔案被刪除,或者替換,那麼將開啟的不是同一個訊息佇列 // //1.建立訊息佇列 msgid=msgget(IPC_KEY,IPC_CREAT | 0664); if(msgid<0){ perror("msgget error"); return -1; } while(1){ struct msgbuf buf; //傳送資料 memset(&buf,0x00,sizeof(struct msgbuf)); buf.mtype=TYPE_C; scanf("%s",buf.mtext); msgsnd(msgid,&buf,1024,0); //2.接收資料 //struct msgbuf這個結構體需要我們自己定義 //msgrcv:預設阻塞的獲取資料 //msgid:操作控制代碼 // //buf:接收資料的結構體,自己定義 //1024 用於指定接收的資料的最大長度,不包含mtype //TYPE_C 用於指定接收的資料型別 //msgflag 0預設 // MSG_NOERROR 當資料長度超過指定長度,則截斷資料 msgrcv(msgid,&buf,1024,TYPE_S,0); printf("server say[%s]\n",buf.mtext); } msgctl(msgid,IPC_RMID,NULL); return 0; }