0

我正在使用 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;

我也想知道如何使用消息队列进行两种方式的通信。我需要创建两个消息队列来完成两个进程之间的通信吗?也欢迎使用相同的示例代码。

谢谢 :)

4

2 回答 2

0

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

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

由于rbuf是一个指针,你应该使用

rbuf=malloc(sizeof(*rbuf));

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

另一个问题是你的比较key-1,我认为应该是(key)-1

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

于 2014-03-25T06:59:51.593 回答
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 & IPC_CREAT) 为 0。

这意味着,您必须致电

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

至少第一次调用这个函数。

于 2014-03-25T07:00:23.710 回答