1. 程式人生 > >利用訊息佇列實現簡單聊天程式

利用訊息佇列實現簡單聊天程式

本篇利用訊息佇列的特性實現簡單的聊天程式,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;
}

在這裡插入圖片描述
在這裡插入圖片描述
在這裡插入圖片描述
在這裡插入圖片描述