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
,只需将其删除即可。
以下代码
- 干净地编译
- 实际有效
- 您需要已经创建了一个
/dev/mqueue
设备。
- 不要使用已知的系统函数名称作为本地函数名称
- 使用
perror()
正确输出错误信息。注意:输出将自动包含与 errno
相关的系统消息
- 注意
(size_t)attr.mq_msgsize
在对 mq_receive()
的调用中的用法
- 注意只需要调用
mq_open()
一次
- 请注意
mqd_t mqdes
和 struct mq_attr
变量在全局文件 space 中,因此所有函数都可以看到它们。另一种可能性是将它们作为参数传递。
- 注意 MSG_SIZE 是通过
#define
定义的,因此它不会在堆栈或文件全局 space 上消耗 space,并且只需要定义一次而不是在每个函数中
- 不应包含代码中未使用的头文件。
- 请注意,在设置各个字段之前,
attr
已全部清除为 0x00
- 请注意,在对 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;
}
我目前正在使用 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 themq_msgsize
attribute of the message queue
[强调我的]
没错,您将 mq_msgsize
属性设置为 msg_size + 1
,然后您收到 msg_size
,它比 mq_msgsize
属性小一。
设置 mq_msgsize
属性时不需要 +1
,只需将其删除即可。
以下代码
- 干净地编译
- 实际有效
- 您需要已经创建了一个
/dev/mqueue
设备。 - 不要使用已知的系统函数名称作为本地函数名称
- 使用
perror()
正确输出错误信息。注意:输出将自动包含与errno
相关的系统消息
- 注意
(size_t)attr.mq_msgsize
在对mq_receive()
的调用中的用法
- 注意只需要调用
mq_open()
一次 - 请注意
mqd_t mqdes
和struct mq_attr
变量在全局文件 space 中,因此所有函数都可以看到它们。另一种可能性是将它们作为参数传递。 - 注意 MSG_SIZE 是通过
#define
定义的,因此它不会在堆栈或文件全局 space 上消耗 space,并且只需要定义一次而不是在每个函数中 - 不应包含代码中未使用的头文件。
- 请注意,在设置各个字段之前,
attr
已全部清除为 0x00 - 请注意,在对 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;
}