error: Invalid argument; while sending msgsnd() message; not matching queue ID
error: Invalid argument; while sending msgsnd() message; not matching queue ID
我刚刚在 linux 上学习 IPC,想出了三个简单的程序。一个是创建(并在功能中管理)消息队列。第二个应该只是将消息发送到第一个创建的队列。第三个程序正在从队列中接收数据。
所有程序都继承自同一个根目录,并根据源代码和二进制文件分配到不同的目录中。
所以让我们专注于创建和发送部分,这也将帮助我修复第三个程序。
添加队列main.c:
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <errno.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#define FAILED -1
int main(int argc, char *argv[]) {
// message data
key_t key;
int msgqid;
if ((key = ftok("../src/main.c", 'Z')) == FAILED) {
perror("ftok");
exit(1);
}
if ((msgqid = msgget(key, 0666 | IPC_CREAT)) == FAILED) { /* create an message queue with owner & group & others permission set to rw- */
perror("msgget");
exit(1);
}
printf("Message Queue %i with key %i, been created [press return to delete]", msgqid, key);
getchar();
if (msgctl(msgqid, IPC_RMID, NULL) == FAILED) {
perror("msgctl");
exit(1);
}
printf("I'm outta here! \n");
return 0;
}
发送main.c:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/msg.h>
#include <stddef.h>
#include <string.h>
#include "../../lib/shared_msgbuf.h" /* mbuf, MSGSZ */
#define FAILED -1
int main(void) {
char s[MSGSZ];
printf("Enter a message: ");
if (fgets(s, sizeof s, stdin) == NULL)
perror("fgets");
else
strcpy(mbuf.mtext, s);
printf("Connecting to the queue... \n", s);
// Setup
key_t key;
int msgqid;
if ((key = ftok("../../adqueue/src/main.c", 'Z')) == FAILED) {
perror("ftok");
exit(1);
}
if (msgqid = msgget(key, 0666) == FAILED) {
perror("msget");
exit(1);
}
printf("\n*CONNECTION ESTABLISHED* \n");
printf("queue id: %i \n", msgqid);
printf("queue key: %d \n", key);
printf("message: %s \n", s);
printf("Sending the message... \n");
if (msgsnd(msgqid, &mbuf, MSGSZ, 0) == FAILED) {
perror("msgsnd");
exit(0);
}
return 0;
}
所以问题是我在尝试发送消息时收到 Invalid argument
错误号。查看数据,我不明白为什么 id 不匹配,因为与队列的连接似乎有效...
示例数据:
./cadqueue
Message Queue 327680 with key 1510081535, been created [press return to delete]
./send
Enter a message: test
Connecting to the queue...
*CONNECTION ESTABLISHED*
queue id: 0
queue key: 1510081535
message: test
Sending the message...
msgsnd: Invalid argument
你的错误来自这一行:
if (msgqid = msgget(key, 0666) == FAILED) {
应该是
if ((msgqid = msgget(key, 0666)) == FAILED) {
在第一种情况下,由于 operator priority,比较 (==
) 在赋值 (=
) 之前完成。
在第二种情况下,括号告诉编译器必须先做什么。
这些是 msgsnd()
所需的头文件
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
为便于移植,发布的代码缺少其中两个头文件包含语句
===========
这条语句:
if (msgqid = msgget(key, 0666) == FAILED) {
缺少应该属于 0666
参数的 IPC_CREAT
===========
mbuf
有两个字段,mtype
字段,必须为正数,> 0
和 mtext
字段。
发布的代码正在设置 mtext
字段,但未能设置 mtype
字段。
=============
这条语句:
printf("Connecting to the queue... \n", s);
有一个输入参数的问题,但它们在 'format string'
中没有格式说明符
============
每次访问同一消息队列时,key
值必须相同。
因此对 ftok()
的调用必须具有相同的参数,否则它们将通过对 msgget()
的调用生成 different/unique 消息队列
============
注意:消息队列不会 'go away' 只是因为程序退出。因此,控制程序(或最后一条消息的最后一个用户)应该调用 msgctl()
来删除消息队列
我刚刚在 linux 上学习 IPC,想出了三个简单的程序。一个是创建(并在功能中管理)消息队列。第二个应该只是将消息发送到第一个创建的队列。第三个程序正在从队列中接收数据。
所有程序都继承自同一个根目录,并根据源代码和二进制文件分配到不同的目录中。
所以让我们专注于创建和发送部分,这也将帮助我修复第三个程序。
添加队列main.c:
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <errno.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#define FAILED -1
int main(int argc, char *argv[]) {
// message data
key_t key;
int msgqid;
if ((key = ftok("../src/main.c", 'Z')) == FAILED) {
perror("ftok");
exit(1);
}
if ((msgqid = msgget(key, 0666 | IPC_CREAT)) == FAILED) { /* create an message queue with owner & group & others permission set to rw- */
perror("msgget");
exit(1);
}
printf("Message Queue %i with key %i, been created [press return to delete]", msgqid, key);
getchar();
if (msgctl(msgqid, IPC_RMID, NULL) == FAILED) {
perror("msgctl");
exit(1);
}
printf("I'm outta here! \n");
return 0;
}
发送main.c:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/msg.h>
#include <stddef.h>
#include <string.h>
#include "../../lib/shared_msgbuf.h" /* mbuf, MSGSZ */
#define FAILED -1
int main(void) {
char s[MSGSZ];
printf("Enter a message: ");
if (fgets(s, sizeof s, stdin) == NULL)
perror("fgets");
else
strcpy(mbuf.mtext, s);
printf("Connecting to the queue... \n", s);
// Setup
key_t key;
int msgqid;
if ((key = ftok("../../adqueue/src/main.c", 'Z')) == FAILED) {
perror("ftok");
exit(1);
}
if (msgqid = msgget(key, 0666) == FAILED) {
perror("msget");
exit(1);
}
printf("\n*CONNECTION ESTABLISHED* \n");
printf("queue id: %i \n", msgqid);
printf("queue key: %d \n", key);
printf("message: %s \n", s);
printf("Sending the message... \n");
if (msgsnd(msgqid, &mbuf, MSGSZ, 0) == FAILED) {
perror("msgsnd");
exit(0);
}
return 0;
}
所以问题是我在尝试发送消息时收到 Invalid argument
错误号。查看数据,我不明白为什么 id 不匹配,因为与队列的连接似乎有效...
示例数据:
./cadqueue
Message Queue 327680 with key 1510081535, been created [press return to delete]
./send
Enter a message: test
Connecting to the queue...
*CONNECTION ESTABLISHED*
queue id: 0
queue key: 1510081535
message: test
Sending the message...
msgsnd: Invalid argument
你的错误来自这一行:
if (msgqid = msgget(key, 0666) == FAILED) {
应该是
if ((msgqid = msgget(key, 0666)) == FAILED) {
在第一种情况下,由于 operator priority,比较 (==
) 在赋值 (=
) 之前完成。
在第二种情况下,括号告诉编译器必须先做什么。
这些是 msgsnd()
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
为便于移植,发布的代码缺少其中两个头文件包含语句
===========
这条语句:
if (msgqid = msgget(key, 0666) == FAILED) {
缺少应该属于 0666
参数的 IPC_CREAT
===========
mbuf
有两个字段,mtype
字段,必须为正数,> 0
和 mtext
字段。
发布的代码正在设置 mtext
字段,但未能设置 mtype
字段。
=============
这条语句:
printf("Connecting to the queue... \n", s);
有一个输入参数的问题,但它们在 'format string'
中没有格式说明符============
每次访问同一消息队列时,key
值必须相同。
因此对 ftok()
的调用必须具有相同的参数,否则它们将通过对 msgget()
============
注意:消息队列不会 'go away' 只是因为程序退出。因此,控制程序(或最后一条消息的最后一个用户)应该调用 msgctl()
来删除消息队列