如何解决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配合使用才会检查队列是否存在。 - 清理旧队列(可选):如果之前已创建权限错误的队列,可先手动删除:
- 查看现有消息队列:
ipcs -q - 删除指定队列:
ipcrm -q <msqid>或ipcrm -Q <key>
- 查看现有消息队列:
内容的提问来源于stack exchange,提问作者Hangel
相关产品推荐
相关产品推荐

