我在C linux中使用消息队列机制发送消息。但是msgrcv函数存在一些问题。它将错误显示为无效参数。 请检查一下。
//msgrcv.c
#include"msgbuf.h"
int main()
{
int msqid;
key_t key;
message_buf *rbuf;
rbuf=malloc(sizeof(*rbuf));
// rbuf->m=malloc(sizeof(M1));
key = ftok("/home/user",'a');
if ((msqid = msgget(key, IPC_CREAT)) ==(key)-1)
{
perror("msgget");
exit(1);
}
/* Receive an answer of message type 1. */
if (msgrcv(msqid, &rbuf, sizeof(rbuf->m), 1, 0) < 0)
{
perror("msgrcv"); //invalid argument to msgrcv
exit(1);
}
/* Print the answer. */
printf("Received message text= %s\n", rbuf->m.cp);
return 0;
}
现在msgbuf.h
//msgbuf.h
typedef struct msgclient
{
int msglen;
int msgtype;
char *cp;
}M1;
typedef struct msgbuf1
{
long mtype;
M1 m;
} message_buf;
我也想知道如何使用消息队列进行双向通信。我是否需要制作两个消息队列才能在两个进程之间完成通信?同样的示例代码也受到欢迎。
谢谢:)
答案 0 :(得分:0)
我已经看到了一个大问题:
message_buf *rbuf;
rbuf=malloc(sizeof(rbuf));
由于rbuf
是指针,你应该使用
rbuf=malloc(sizeof(*rbuf));
您的原始文件为您提供指针的大小(通常是当前编译器中的四个或八个字节),而不是您需要的message_buf
结构的大小。
另一个问题是您与key-1
的比较,我应该是(key)-1
。
您的msgget
可能会失败,并且由于此错误检查,您没有检测到它。这意味着msgrecv
将使用-1
作为队列ID,解释其中的失败。
答案 1 :(得分:0)
我猜这个
if ((msqid = msgget(key, 0666)) ==key-1)
应该是
if ((msqid = msgget(key, 0666)) == -1)
来自msgrcv
<强>错误强>
如果出现以下情况,msgrcv()函数将失败:
...
[EINVAL]
msqid 不是有效的邮件队列标识符。
此外,message_buf.m
不能是指针而是成员
typedef struct msgbuf1
{
long mtype;
M1 m;
} message_buf;
然后,您可以将此通话保存到malloc
rbuf->m=malloc(sizeof(M1));
并且对msgrcv
的调用应为
if (msgrcv(msqid, rbuf, sizeof(rbuf->m), 1, 0) < 0)
因为否则,msgrcv
将覆盖您的筹码。
更新
来自msgget
<强>错误强>
[ENOENT]
参数键不存在消息队列标识符,并且(msgflg&amp; IPC_CREAT)为0.
这意味着,您必须致电
if ((msqid = msgget(key, IPC_CREAT | 0666)) == -1)
至少第一次调用此函数。