消息队列的简单实现(客户端A,客户端B)

下面是两个相互通信进程的简单实现,一个代表客户端A,一个代表客户端B


/***************************************
                客户端A
    发送TYPEB类型的数据到客户端B
    读取发送到客户端A的TYPEA类型的数据
***************************************/
#include <stdio.h>
#include <signal.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdlib.h>
#include <errno.h>

#define N 64
#define TYPEA 100
#define TYPEB 200

typedef struct{
    long mtype;   //消息类型
    char mtext[N];  //正文段
}MSG;

int main()
{
    key_t key;
    pid_t pid;
    int msgid;
    MSG buf;
    memset(buf.mtext, 0, N); //先将正文段初始化
    
    if ((key = ftok("/", 1)) == -1) {perror("get key"); return -1;}  //创建key
    if ((msgid = msgget(key, 0666 | IPC_CREAT)) == -1) {perror("msgget"); return -1;} //创建消息队列,没有则创建,有了则打开,并将其ID传给msgid
    if ((pid = fork()) == -1) {perror("fork"); return -1;}
    
    if (pid == 0) /*子进程从消息队列读取TYPEA类型的消息*/
    {
        while (1)
        {
            if (-1 == msgrcv(msgid, &buf, N, TYPEA, 0))
            {
                perror("msgrcv");
                return -1;
            }
            printf("rcv----%s", buf.mtext);
            if (strncmp(buf.mtext, "quit", 4) == 0)
            {
                kill(getppid(), SIGKILL); //杀死父进程
                
                if (-1 == msgctl(msgid, IPC_RMID, NULL)) //删除消息队列
                {
                    perror("msg rm");
                    exit(-1);
                }
                exit(0);
            }
        }
    }
    else  /*父进程向消息队列发送TYPEB类型的消息*/
    {
        buf.mtype = TYPEB;  
        while (1)
        {
            fgets(buf.mtext, N, stdin);
            if (-1 == msgsnd(msgid, &buf, strlen(buf.mtext)+1, 0)) //发送的是正文段的大小,而不是结构体的大小
            {
                perror("msgsnd");
                return -1;
            }
            if (strncmp(buf.mtext, "quit", 4) == 0)
            {
                kill(pid, SIGKILL); //杀死子进程
                exit(0);
            }
        }
    }
    
    return 0;
}



/***************************************
                客户端B
    发送TYPEA类型的数据到客户端A
    读取发送到客户端B的TYPEB类型的数据
***************************************/
#include <stdio.h>
#include <signal.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdlib.h>
#include <errno.h>

#define N 64
#define TYPEA 100
#define TYPEB 200

typedef struct{
    long mtype;   //消息类型
    char mtext[N];  //正文段
}MSG;

int main()
{
    key_t key;
    pid_t pid;
    int msgid;
    MSG buf;
    memset(buf.mtext, 0, N); //先将正文段初始化
    
    if ((key = ftok("/", 1)) == -1) {perror("get key"); return -1;}
    if ((msgid = msgget(key, 0666 | IPC_CREAT)) == -1) {perror("msgget"); return -1;}
    if ((pid = fork()) == -1) {perror("fork"); return -1;}
    
    if (pid == 0) /*child process receive message TYPEA*/
    {
        while (1)
        {
            if (-1 == msgrcv(msgid, &buf, N, TYPEB, 0))
            {
                perror("msgrcv");
                exit(-1);
            }
            printf("rcv----%s", buf.mtext);
            if (strncmp(buf.mtext, "quit", 4) == 0)
            {
                kill(getppid(), SIGKILL);
                
                if (-1 == msgctl(msgid, IPC_RMID, NULL))
                {
                    perror("msg rm");
                    exit(-1);
                }
                exit(0);
            }
        }
    }
    else  /*parent process send message TYPEA*/
    {
        buf.mtype = TYPEA;   
        while (1)
        {
            fgets(buf.mtext, N, stdin);
            if (-1 ==msgsnd(msgid, &buf, strlen(buf.mtext)+1, 0))
            {
                perror("msgsnd");
                return -1;
            }
            if (strncmp(buf.mtext, "quit", 4) == 0)
            {
                kill(pid, SIGKILL);
                exit(0);
            }
        }
    }
    
    return 0;
}




  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值