【问题标题】:error in msgrcv() :receiving data through message queue in Cmsgrcv() 中的错误:通过 C 中的消息队列接收数据
【发布时间】:2014-05-02 20:47:54
【问题描述】:

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

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

谢谢:)

【问题讨论】:

    标签: c linux ipc message-queue msgrcv


    【解决方案1】:

    我猜这个

    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)
    

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

    【讨论】:

    • 不,先生。在进行上述更改之后,它使用 msgget() 给出错误。
    • 在你的问题中,你说msgrcvmsggetmsgrcv 是否有错误?
    • msgrcv: Invalid argument 这是我在编译后得到的 ./a.out。
    • 是的。我认为 msqid 正在制造问题。知道如何生成它吗?
    • 修复if (msgget(...) == -1)并查看返回值。创作本身看起来不错。
    【解决方案2】:

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

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

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

    rbuf=malloc(sizeof(*rbuf));
    

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

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

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

    【讨论】:

    • 我说这是一个问题,可能还有其他问题。无论如何,它需要修复以防止未定义的行为。
    • 是的。知道了。 :) 但是 msgrcv 的错误仍然存​​在。 msgrcv:参数无效
    • 检查更新,你的 msgget 检查是错误的,所以那里的失败会导致 msgrecv 失败。
    • 已更新。仍然 msgrcv: Permission denied 。但是,如果 msqid=msgget(key,IPC_CREAT|0666) 将 msqid 设为 -1。
    • 那是一个不同的错误,这个问题得到了回答,它不是用来对话的。我建议你对新问题提出一个新问题。
    猜你喜欢
    • 2011-07-15
    • 2013-12-06
    • 2014-05-04
    • 2014-05-03
    • 2018-09-09
    • 1970-01-01
    • 2010-09-19
    • 2012-11-16
    • 2014-02-01
    相关资源
    最近更新 更多