mq_send发送结构体/字符串时报Message too long错误求助
问题描述
使用POSIX消息队列发送数据时,调用mq_send始终报错Message too long,即使调整mq_msgsize参数也无法解决。已排除接收端影响,测试发送短字符串仍出现相同错误。
原始发送代码
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <pthread.h> #include <mqueue.h> #include "sctp.h" #include "s1ap.h" #include "messages.h" void send_to_s1ap(void); int main() { pthread_t tid; pthread_create(&tid, NULL, s1ap, (void *)&tid); pthread_create(&tid, NULL, sctp, (void *)&tid); send_to_s1ap(); pthread_exit(NULL); return 0; } void send_to_s1ap(void) { int status = 0; mqd_t mqfd; struct mq_attr attr; int open_flags = 0; int priority_of_msg; message msg; attr.mq_maxmsg = 100; attr.mq_msgsize = 100; attr.mq_flags = 0; open_flags = O_WRONLY|O_CREAT; mqfd = mq_open("/s1ap_queue",open_flags,0660,&attr); if (mqfd == -1) { printf("mq_open failure from main\n"); return; } /* Fill in a test message buffer to send */ msg.msg_id = 1; msg.data[0] = 'P'; msg.data[1] = 'R'; msg.data[2] = 'I'; msg.data[3] = 'O'; msg.data[4] = 'R'; msg.data[5] = 'I'; msg.data[6] = 'T'; msg.data[7] = 'Y'; msg.data[8] = '1'; msg.data[9] = 'a'; priority_of_msg = 1; status = mq_send(mqfd,(const char *) &msg,sizeof(msg),priority_of_msg); if (status == -1) { perror("mq_send failure on mqfd\n"); } else { printf("successful call to mq_send\n"); } if (mq_close(mqfd) == -1) { printf("mq_close failure on mqfd"); } }
messages.h定义
#define max_msg_size 10 typedef struct message { int msg_id; char data[max_msg_size]; } message;
测试补充代码
发送短字符串仍报错:
void send_to_s1ap(void) { int status = 0; mqd_t mqfd; struct mq_attr attr; int open_flags = 0; int priority_of_msg; char buffer2[12] = "Hello world"; attr.mq_maxmsg = 10; attr.mq_msgsize = 100; attr.mq_flags = 0; attr.mq_curmsgs = 0; open_flags = O_WRONLY|O_CREAT; mqfd = mq_open("/s1ap_queue",open_flags,0660,&attr); if (mqfd == -1) { printf("mq_open failure from main\n"); return; } /* Fill in a test message buffer to send */ priority_of_msg = 1; status = mq_send(mqfd,buffer2,sizeof(buffer2),priority_of_msg); if (status == -1) { perror("mq_send failure on mqfd\n"); } else { printf("successful call to mq_send\n"); } if (mq_close(mqfd) == -1) { printf("mq_close failure on mqfd"); } }
解决方案
核心原因
目标消息队列/s1ap_queue已经存在于系统中,调用mq_open时仅使用O_CREAT标志的情况下,传入的attr参数会被直接忽略,队列会沿用最初创建时的属性。如果最初创建的队列mq_msgsize远小于当前要发送的数据大小,就会触发Message too long错误。
解决步骤
删除已存在的消息队列
直接在终端执行命令删除旧队列:rm /dev/mqueue/s1ap_queue或者在代码中
mq_open前调用删除接口(需确保有足够权限):mq_unlink("/s1ap_queue");这样重新创建队列时会使用你指定的新属性。
修改
mq_open标志避免误用旧队列
添加O_EXCL标志,若队列已存在则mq_open直接失败,避免意外使用旧属性的队列:open_flags = O_WRONLY|O_CREAT|O_EXCL;验证队列实际属性
创建队列后,可通过mq_getattr确认实际生效的属性,排查配置是否正确:struct mq_attr actual_attr; mq_getattr(mqfd, &actual_attr); printf("实际消息最大长度: %ld\n", actual_attr.mq_msgsize);
内容的提问来源于stack exchange,提问作者Haris
相关产品推荐
相关产品推荐

