Linux ipc msgsnd()失败

时间:2016-10-14 15:46:14

标签: c unix ipc

我正在使用unix消息队列编写程序。问题是这个,程序报告我"错误:22:无效的参数"。我已经知道了,但它并不满足我的搜索。这是简单的代码:

    bool msg::send(int key, void* data)
{
    (void) data;
    bool res = false;
    m_msgId = msgget(key, m_mask);
    if (m_msgId == -1) {
        // noone create it
        if ((m_msgId = msgget(key, m_mask | IPC_CREAT)) == -1) {
            fprintf(stderr, "Error creating message: %d:(%s)\n",
                                            errno,
                                            strerror(errno));
            return res;
        }
    }

    union {
       msg m;
       char c[sizeof(msg)];
    } u = {*this}; // it`s a deep copy

    // here the program fails //
    int ret = msgsnd(m_msgId, u.c,
                     sizeof(msg), IPC_NOWAIT);
    if (ret == -1) {
        if (errno != EAGAIN) {
           // here is errno 22 //
            fprintf(stderr, "Error creating message: %d:(%s)\n",
                                            errno,
                                            strerror(errno));

            return res;

        } else {
            if (msgsnd(m_msgId, u.c,
                       sizeof(msg), 0) == -1) {
                fprintf(stderr, "Error creating message: %d:(%s)\n",
                                                errno,
                                                strerror(errno));
                res = false;
            }
        }
    }
    res = true;
    return res;
}

如果我尝试发送正常的字符串,例如" 1234567"没关系。但是这个缓冲区发送失败。我做错了什么? 感谢。

1 个答案:

答案 0 :(得分:2)

msgsnd的一个EINVAL条件是"the value of mtype is less than 1"

msgsnd期望发送缓冲区是 long 描述消息类型( mtype ),后跟消息本身。您错误地没有设置消息类型,因此msgsnd会将消息的第一个 - 字节解释为 mtype 。当邮件为"1234567"但邮件失败并显示*this时,这种情况就会发生。

你想要定义这样的东西:

struct mymsg {
  long mtype;
  char mtext[SUFFICIENTLY_LARGE];
};

并在明确设置 mtype > = 1时将消息复制到 mtext 中的内存中。