POSIX 消息队列,错误号 90,消息太长

POSIX Message queues, errno 90, message too long

我目前正在使用 POSIX 消息队列进行最小 IPC。我有一个管道只将 uint8_t 作为命令传递,而另一个管道将传递长度最多为 128 个字符的字符串。命令管道工作正常。但是 stringpipe 总是给我错误号 90,这意味着 message too long。我已经写了一个最小的例子来演示这个问题(请注意:我保持最小,所以除了接收时的错误之外没有任何错误处理)。

#include <fcntl.h>
#include <sys/stat.h>
#include <mqueue.h>
#include <errno.h>
#include <time.h>
#include <string.h>
#include <stdio.h>

int msg_size = 128;

int send()
{
    struct mq_attr attr = {0, 10, msg_size + 1, 0};
    mqd_t mq = mq_open("/test", O_RDWR | O_CREAT, 00644, &attr);
    char msg[msg_size] = {0};
    strncpy(msg, "this_is_a_test", msg_size);
    mq_send(mq, msg, msg_size, 0);
}

int recv()
{
    struct mq_attr attr = {0, 10, msg_size + 1, 0};
    mqd_t mq = mq_open("/test", O_RDWR | O_CREAT, 00644, &attr);
    char msg[msg_size] = {0};
    int res = mq_receive(mq, msg, msg_size, NULL);
    if (res == -1)
    {
        printf("Errno: %d\n", errno);
    }
    else
    {
        printf("Message: %s\n", msg); 
    }
}

int main()
{
    send();
    recv();
    return 0;
}

编译:

g++ -o mq mq.c -lrt

如果你阅读 the mq_receive manual page 你会发现 EMSGSIZE 意味着

msg_len was less than the mq_msgsize attribute of the message queue

[强调我的]

没错,您将 mq_msgsize 属性设置为 msg_size + 1,然后您收到 msg_size,它比 mq_msgsize 属性小一。

设置 mq_msgsize 属性时不需要 +1,只需将其删除即可。

以下代码

  1. 干净地编译
  2. 实际有效
  3. 您需要已经创建了一个 /dev/mqueue 设备。
  4. 不要使用已知的系统函数名称作为本地函数名称
  5. 使用perror()正确输出错误信息。注意:输出将自动包含与 errno
  6. 相关的系统消息
  7. 注意 (size_t)attr.mq_msgsize 在对 mq_receive()
  8. 的调用中的用法
  9. 注意只需要调用mq_open()一次
  10. 请注意 mqd_t mqdesstruct mq_attr 变量在全局文件 space 中,因此所有函数都可以看到它们。另一种可能性是将它们作为参数传递。
  11. 注意 MSG_SIZE 是通过 #define 定义的,因此它不会在堆栈或文件全局 space 上消耗 space,并且只需要定义一次而不是在每个函数中
  12. 不应包含代码中未使用的头文件。
  13. 请注意,在设置各个字段之前,attr 已全部清除为 0x00
  14. 请注意,在对 mq_send() 的调用中仅指定了消息的实际长度,因此没有垃圾 sent/received

现在是代码

#include <fcntl.h>
#include <sys/stat.h>
#include <mqueue.h> // mq_open(), mq_send(), mq_receive()

//#include <errno.h>
//#include <time.h>
#include <string.h> // strncpy(), strlen()

#include <stdio.h>  // printf(), perror()
#include <stdlib.h> // exit(), EXIT_FAILURE

#define MSG_SIZE  (128)

static mqd_t mqdes = -1;
static struct mq_attr attr;

void sendQueue()
{
    char msg[ MSG_SIZE ] = {0};
    strncpy(msg, "this_is_a_test", MSG_SIZE);
    if( -1 == mq_send(mqdes, msg, strlen(msg), 5) )
    {
        perror( "mq_send failed" );
        exit( EXIT_FAILURE );
    }

    else
    {
        printf( "%s\n", "msg sent successfully");
    }
}

void recvQueue()
{
    char msg[ MSG_SIZE ] = {0};

    ssize_t res = mq_receive(mqdes, msg, (size_t)attr.mq_msgsize, NULL);
    if (res == -1)
    {
        perror("mq_receive failed");
    }

    else
    {
        printf("Message: %s\n", msg);
    }
}

int main( void )
{
    mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;

    memset( &attr, 0x00, sizeof(struct mq_attr) );
    attr.mq_maxmsg = 3;
    attr.mq_msgsize = MSG_SIZE;
    attr.mq_flags = 0;
    attr.mq_curmsgs = 0;

    char *queueName = "/test";

    mqdes = mq_open( queueName, O_RDWR|O_CREAT, mode, &attr);
    if( -1 == mqdes )
    {
        perror( "mq_open failed");
        exit( EXIT_FAILURE );
    }

    // implied else, mq_open successful


    sendQueue();
    recvQueue();
    return 0;
}