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

如何解决C语言中使用msgrcv时出现的Permission denied错误

解决C语言消息队列msgrcv权限拒绝问题

问题根源

你的代码在调用msgget创建消息队列时,未指定有效的权限位参数,导致创建的队列权限设置异常(通常默认无读写权限);同时打开已存在队列的逻辑有误,进一步引发权限问题。

修复方案及代码

修复后的完整代码

typedef struct {
    long id;
    char mes[20];
} message;

#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <errno.h>

int main() {
    
    key_t cle = ftok(".", 0);
    
    if (cle == -1) {
        perror("ftok");
        return EXIT_FAILURE;
    }
    
    // 创建消息队列,必须指定权限位(示例用0666,可按需调整)
    int msqId = msgget(cle, IPC_CREAT | IPC_EXCL | 0666);
    if (msqId == -1) {
        // 仅当队列已存在时,尝试打开现有队列
        if (errno == EEXIST) {
            msqId = msgget(cle, 0);
            if (msqId == -1) {
                perror("msgget (open existing)");
                return EXIT_FAILURE;
            }
        } else {
            perror("msgget (create)");
            return EXIT_FAILURE;
        }
    }

    message mes;

    while (1) {
        int received = msgrcv(msqId, &mes, sizeof(message) - sizeof(long), 0, 0);
        
        if (received == -1) {
            perror("msgrcv");
            return EXIT_FAILURE;
        }
        
        printf("Server: message received - type: %ld, content: %s\n", mes.id, mes.mes);
    }

    return EXIT_SUCCESS;
}

关键修改说明

  • 添加权限位参数:创建队列时必须附加权限位(如0666,表示所有用户可读可写),否则队列权限会被设置为无效值,导致后续msgrcv无权限执行。
  • 修正队列打开逻辑:当msgget因队列已存在失败时,先判断错误码为EEXIST,再用msgget(cle, 0)打开现有队列——单独使用IPC_EXCL标志无意义,该标志仅和IPC_CREAT配合使用才会检查队列是否存在。
  • 清理旧队列(可选):如果之前已创建权限错误的队列,可先手动删除:
    1. 查看现有消息队列:ipcs -q
    2. 删除指定队列:ipcrm -q <msqid> 或 ipcrm -Q <key>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 06:25:06