msgrcv()中的错误:通过C中的消息队列接收数据

时间:2014-03-25 06:51:14

标签: c linux ipc message-queue msgrcv

我在C linux中使用消息队列机制发送消息。但是msgrcv函数存在一些问题。它将错误显示为无效参数。 请检查一下。

//msgrcv.c
#include"msgbuf.h"
int main()
{
      int msqid;
      key_t key;
      message_buf  *rbuf;
      rbuf=malloc(sizeof(*rbuf));
     // rbuf->m=malloc(sizeof(M1));

      key = ftok("/home/user",'a');
      if ((msqid = msgget(key, IPC_CREAT)) ==(key)-1)
      {
         perror("msgget");
         exit(1);
      }

      /* Receive an answer of message type 1.   */
      if (msgrcv(msqid, &rbuf, sizeof(rbuf->m), 1, 0) < 0)
      {
           perror("msgrcv");  //invalid argument to msgrcv
           exit(1);
       }
         /* Print the answer.  */
       printf("Received message text= %s\n", rbuf->m.cp);
      return 0;
   }

现在msgbuf.h

 //msgbuf.h
typedef struct msgclient
{
   int msglen;
   int msgtype;
   char *cp;
}M1;

typedef struct msgbuf1
{
   long    mtype;
   M1      m;
} message_buf;

我也想知道如何使用消息队列进行双向通信。我是否需要制作两个消息队列才能在两个进程之间完成通信?同样的示例代码也受到欢迎。

谢谢:)

2 个答案:

答案 0 :(得分:0)

我已经看到了一个大问题:

message_buf  *rbuf;
rbuf=malloc(sizeof(rbuf));

由于rbuf指针,你应该使用

rbuf=malloc(sizeof(*rbuf));

您的原始文件为您提供指针的大小(通常是当前编译器中的四个或八个字节),而不是您需要的message_buf结构的大小。

另一个问题是您与key-1的比较,我应该是(key)-1

您的msgget可能会失败,并且由于此错误检查,您没有检测到它。这意味着msgrecv将使用-1作为队列ID,解释其中的失败。

答案 1 :(得分:0)

我猜这个

if ((msqid = msgget(key, 0666)) ==key-1)

应该是

if ((msqid = msgget(key, 0666)) == -1)

来自msgrcv

  

<强>错误
  如果出现以下情况,msgrcv()函数将失败:
  ...
  [EINVAL]
       msqid 不是有效的邮件队列标识符。

此外,message_buf.m不能是指针而是成员

typedef struct msgbuf1
{
   long    mtype;
   M1      m;
} message_buf;

然后,您可以将此通话保存到malloc

rbuf->m=malloc(sizeof(M1));

并且对msgrcv的调用应为

if (msgrcv(msqid, rbuf, sizeof(rbuf->m), 1, 0) < 0)

因为否则,msgrcv将覆盖您的筹码。

更新

来自msgget

  

<强>错误
  [ENOENT]
      参数键不存在消息队列标识符,并且(msgflg&amp; IPC_CREAT)为0.

这意味着,您必须致电

if ((msqid = msgget(key, IPC_CREAT | 0666)) == -1)

至少第一次调用此函数。