利用消息队列实现简单聊天程序

本篇利用消息队列的特性实现简单的聊天程序,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;
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_40853073/article/details/83930043