使用消息队列进行全双工通信,连续打印消息

时间:2017-07-24 07:25:04

标签: c ipc

program1.c

#include <stdio.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/types.h>
#include <string.h>
#define SEND_KEY 2
#define RCV_KEY 3

typedef struct msgbuf 
{
    long mtype;     /* message type, must be > 0 */
    char mtext[100];  /* message data */
} MSG_BUF;
int main()
{
    int msg_id;
    MSG_BUF mbuf_snd,mbuf_rcv;

    if((msg_id=msgget(5,IPC_CREAT |0644))<0)
        perror("msgget");

    if(fork()==0)
    {
        // child is receiving
        while(1) {
            if((msgrcv(msg_id,&mbuf_rcv,sizeof(mbuf_rcv.mtext),RCV_KEY,0))<0)
                perror("msgrcv");
            printf("Message : %s\n",mbuf_rcv.mtext);
        }
    }
    else
    {
        // Parent is writing
        while(1){
            mbuf_snd.mtype=SEND_KEY;
            printf("Enter the message\n");
            scanf(" %[^\n]",mbuf_snd.mtext);
            if((msgsnd(msg_id,&mbuf_snd,strlen(mbuf_snd.mtext)+1,0))<0)
                perror("msgsnd");
        }
    }
    return 0;
}

program2.c

#include <stdio.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/types.h>
#include <string.h>
#define SEND_KEY 3
#define RCV_KEY 2

typedef struct msgbuf {
        long mtype;     /* message type, must be > 0 */
        char mtext[100];  /* message data */
}MSG_BUF;
int main()
{
    int msg_id;
    MSG_BUF mbuf_snd,mbuf_rcv;
    if((msg_id=msgget(5,IPC_CREAT |0644))<0)
        perror("msgget");
    if(fork()==0)
    {
        //child is receiving 
        while(1){
            if((msgrcv(msg_id,&mbuf_rcv,sizeof(mbuf_rcv.mtext),RCV_KEY,0))<0)
                perror("msgrcv");
            printf("Message : %s\n",mbuf_rcv.mtext);
        }
    }
    else
    {
        // Parent is writing
        while(1){
            mbuf_snd.mtype=SEND_KEY;
            printf("Enter the message\n");
            scanf(" %[^\n]",mbuf_snd.mtext);
            if((msgsnd(msg_id,&mbuf_snd,strlen(mbuf_snd.mtext)+1,0))<0)
                perror("msgsnd");
            }
    }
    return 0;
}

Program1 parent正在为mtype 2和从mtype 3接收消息的子节点编写消息。

Program2 parent正在为mtype 3和从mtype 2接收mesaage的孩子写消息。

但是在编译之后它没有给出任何错误。但是当我执行它时,它会在屏幕上不断打印数据。我的要求是它应该在打印数据后停止并等待下一个数据。

你能解释一下我发生了什么吗?

1 个答案:

答案 0 :(得分:1)

您的问题来自输入功能:

当您致电scanf时,\n会停留在输入流中,并且每次再次调用scanf时,mbuf_snd.mtext为空且\n停留在输入流...

<强>修正:

scanf("%[^\n]%*c",mbuf_snd.mtext);

<强>说明:

  • %[^\n]会收到您想要的消息,
  • %*c将从输入流中删除\n。 (*告诉scanf不要存储读取的字符)

其他方法:

您可以使用fgets函数从输入流中获取一行,它不如scanf棘手:

fgets(mbuf_snd.mtext, sizeof mbuf_snd.mtext, stdin)

fgets的一个优点是很容易检测到没有模式数据可以从输入流中读取。