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

时间:2016-04-29 09:00:50

标签: c linux posix

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

2 个答案:

答案 0 :(得分:1)

如果您阅读the mq_receive manual page,您会看到EMSGSIZE表示

  

msg_len <消息队列的mq_msgsize属性

[强调我的]

这是真的,您将mq_msgsize属性设置为msg_size + 1,然后您收到的msg_sizemq_msgsize属性少一个。

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

答案 1 :(得分:0)

以下代码

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

    #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;
    }