You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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错误。

解决步骤

  1. 删除已存在的消息队列
    直接在终端执行命令删除旧队列:

    rm /dev/mqueue/s1ap_queue
    

    或者在代码中mq_open前调用删除接口(需确保有足够权限):

    mq_unlink("/s1ap_queue");
    

    这样重新创建队列时会使用你指定的新属性。

  2. 修改mq_open标志避免误用旧队列
    添加O_EXCL标志,若队列已存在则mq_open直接失败,避免意外使用旧属性的队列:

    open_flags = O_WRONLY|O_CREAT|O_EXCL;
    
  3. 验证队列实际属性
    创建队列后,可通过mq_getattr确认实际生效的属性,排查配置是否正确:

    struct mq_attr actual_attr;
    mq_getattr(mqfd, &actual_attr);
    printf("实际消息最大长度: %ld\n", actual_attr.mq_msgsize);
    

内容的提问来源于stack exchange,提问作者Haris

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 05:24:58