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

消息队列Sender程序发送字节数显示为0问题求助

解决Sender程序发送字节数显示为0的问题

代码中的关键错误

  • 文件大小未初始化且未获取:fileSize初始值为-1,循环条件totalBytesRead < fileSize(0 < -1)永远不成立,导致读取文件的循环完全未执行,totalBytesRead始终为0。
  • read函数参数错误:read的第三个参数是最大读取字节数,你传入了初始为0的bytesRead,导致首次读取0字节,后续逻辑全部混乱。
  • mq_send参数顺序完全错误:mq_send的正确参数顺序为mq_send(队列ID, 缓冲区指针, 消息长度, 优先级),你颠倒了缓冲区和长度的位置,还错误传入4096作为固定长度。
  • 循环计数逻辑错误:将read的返回值直接赋值给totalBytesRead,后续又执行totalBytesRead += bytesRead,导致计数完全错误;同时判断文件结束的条件逻辑颠倒。
  • 未检查mq_open返回值:如果消息队列不存在,mq_open会返回-1,但你未做错误处理,程序会继续执行无效逻辑。
  • 未实现结束标记消息:作业要求发送优先级为2的空消息告知接收方传输结束,代码中未完成该逻辑。
  • 硬编码队列名称:定义了宏MSQ_NAME却在mq_open中硬编码路径,导致代码一致性问题。
  • 缺少bool类型依赖:使用bool类型但未包含stdbool.h头文件,可能引发编译错误。

修复后的完整代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <mqueue.h>
#include <unistd.h>
#include <stdbool.h>  // 新增:支持bool类型

#define MSQ_NAME "/cpsc351queue"

int main(int argc, char** argv)
{   
    off_t fileSize = 0;
    char buff[4096];
    mqd_t qid = -1;
    int totalBytesSent = 0;  // 重命名为更准确的语义
    ssize_t bytesRead = 0;   // 匹配read返回值的ssize_t类型
    bool finishedReading = false;
    
    mq_attr attr;
    attr.mq_flags = 0;
    attr.mq_maxmsg = 10;
    attr.mq_msgsize = 4096;
    attr.mq_curmsgs = 0;

    // 参数合法性检查
    if(argc < 2)
    {
        fprintf(stderr, "USAGE: %s <FILE NAME>\n", argv[0]);
        exit(1);
    }

    // 打开目标文件
    int fd = open(argv[1], O_RDONLY);
    if(fd < 0)
    {
        perror("open");
        exit(1);
    }

    // 获取文件大小
    struct stat fileStat;
    if(fstat(fd, &fileStat) < 0)
    {
        perror("fstat");
        close(fd);
        exit(1);
    }
    fileSize = fileStat.st_size;

    // 打开消息队列:仅写模式,队列不存在则报错
    qid = mq_open(MSQ_NAME, O_WRONLY);
    if(qid == (mqd_t)-1)
    {
        perror("mq_open");
        close(fd);
        exit(1);
    }

    // 循环读取文件并发送消息
    while(!finishedReading)
    {
        // 每次最多读取4096字节
        bytesRead = read(fd, buff, sizeof(buff));
        if(bytesRead < 0)
        {
            perror("read");
            mq_close(qid);
            close(fd);
            exit(1);
        }
        else if(bytesRead == 0)
        {
            // 文件读取完毕
            finishedReading = true;
            break;
        }

        // 发送读取到的内容,优先级设为1
        if(mq_send(qid, buff, bytesRead, 1) < 0)
        {
            perror("mq_send");
            mq_close(qid);
            close(fd);
            exit(1);
        }

        totalBytesSent += bytesRead;
    }

    // 发送优先级为2的空消息,告知接收方传输结束
    if(mq_send(qid, "", 0, 2) < 0)
    {
        perror("mq_send (end marker)");
        mq_close(qid);
        close(fd);
        exit(1);
    }

    fprintf(stderr, "Sent a total of %d bytes\n", (int)totalBytesSent);
    
    // 关闭所有资源
    mq_close(qid);
    close(fd);
    return 0;
}

修复核心说明

  1. 正确获取文件大小:通过fstat获取打开文件的实际大小,确保读取循环能正常执行。
  2. 修正系统调用参数:调整read和mq_send的参数顺序与取值,符合函数原型要求。
  3. 修复计数逻辑:用totalBytesSent累计实际发送的字节数,每次读取后累加有效读取长度。
  4. 完善错误处理:对所有系统调用的返回值做检查,确保队列不存在时直接报错退出,符合作业要求。
  5. 实现结束标记:补充发送优先级为2的空消息逻辑,完成作业要求的传输结束通知。
  6. 类型匹配与代码一致性:修正变量类型,使用宏定义的队列名称,避免硬编码错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 11:10:23