[英]POSIX Message queues, errno 90, message too long
I am currently doing a minimal IPC using POSIX Message Queues. 我目前正在使用POSIX消息队列进行最小的IPC。 I have one pipe that only will pass
uint8_t
's as commands and another pipe that will pass strings with a length up to 128 characters. 我有一个管道仅将
uint8_t
作为命令传递,而另一个管道将传递最长为128个字符的字符串。 The command pipe is working fine. 命令管道运行正常。 But the stringpipe will always give me errno number 90, which means
message too long
. 但是弦管总是给我错误号90,这意味着
message too long
。 I have written a minimal example demonstrating the issue (please note: i kept it minimal, so there is no errorhandling whatsoever besides the error upon receiving). 我已经写了一个最小的示例来演示该问题(请注意:我将其保持在最小限度,因此除了接收到错误以外,没有任何错误处理)。
#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;
}
Compile with: 编译:
g++ -o mq mq.c -lrt
If you read the mq_receive
manual page you will will see that EMSGSIZE
means 如果您阅读
mq_receive
手册页,您将看到EMSGSIZE
意味着
msg_len
was less than themq_msgsize
attribute of the message queuemsg_len
小于消息队列的mq_msgsize
属性
[Emphasis mine] [强调我的]
And that's true, you set the mq_msgsize
attribute to msg_size + 1
and then you receive msg_size
which is one less than the mq_msgsize
attribute. 的确如此,您将
mq_msgsize
属性设置为msg_size + 1
,然后收到的msg_size
比mq_msgsize
属性小一。
You don't need that +1
when setting the mq_msgsize
attribute, just remove it. 设置
mq_msgsize
属性时不需要+1
,只需删除它即可。
the following code 以下代码
/dev/mqueue
device already created. /dev/mqueue
设备。 perror()
to properly output error messages. perror()
正确输出错误消息。 Note: the output will automatically include the system message related to errno
errno
相关的系统消息 (size_t)attr.mq_msgsize
in the call to mq_receive()
(size_t)attr.mq_msgsize
在对mq_receive()
的调用中的mq_receive()
mq_open()
once mq_open()
mqd_t mqdes
and struct mq_attr
variables are in the file global space so all the functions can see them. mqd_t mqdes
和struct mq_attr
变量位于文件全局空间中,因此所有函数都可以看到它们。 An alternate possibility is to pass them as parameters. #define
so it does not consume space on the stack nor on the file global space and only needs to be defined once rather than in each function #define
定义的,因此它不会占用堆栈空间或文件全局空间,只需要定义一次,而不是在每个函数中定义一次 attr
is cleared to all 0x00 before setting the individual fields attr
清除为全0x00 and now the code 现在的代码
#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;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.