IPC在C中使用消息队列:接收错误

IPC在C中使用消息队列:接收错误,c,linux,ipc,message-queue,C,Linux,Ipc,Message Queue,我正在C linux中实现消息队列。我正在发送一个integer=17并接收integer=0。请参阅下面的内容,让我知道我的msgsnd和msgrcv功能有什么问题。 请注意:将rbuf数据存储在rbuf->m->msglen或rbuf->mtype中 在发送过程中 msgsnd(msqid, sbuf,sizeof(int), 0); printf("\nmsglen = %d",rbuf->m->msglen); // 17 在接收过程中。两者都有相同的msqid。我已经核

我正在C linux中实现消息队列。我正在发送一个
integer=17
并接收
integer=0
。请参阅下面的内容,让我知道我的
msgsnd
msgrcv
功能有什么问题。 请注意:将
rbuf
数据存储在
rbuf->m->msglen
rbuf->mtype

在发送过程中

msgsnd(msqid, sbuf,sizeof(int), 0);
printf("\nmsglen = %d",rbuf->m->msglen);  // 17
在接收过程中。两者都有相同的msqid。我已经核实过了

msgrcv(msqid, rbuf, sizeof(int), 1, 0);
printf("\nmsglen = %d",rbuf->m->msglen); // 0

//msqid=98305, some valid id
这是我在另一个文件中定义的结构定义

typedef struct message1
{
    int msglen;
    unsigned char *cp;
}msg1;

typedef struct msgbuf
{
    long    mtype;
    msg1    *m;
} message_buf;
//头文件
#包括“msgbuf.h”//我在其中放置了我的结构
#定义自动1
#定义用户_数据2
int main()
{
int msgflg=IPC|u CREAT | 0666,ch,len=0;
大小\u t msgsize=0;
int msqid;
钥匙(t)钥匙;;
消息_buf*sbuf;
查尔安斯;
字符*数据;
key=ftok(“/home/user”,15);
printf(“您想发送消息吗\t”);
scanf(“%c”和“&ans”);
getchar();
如果((ans=='y'| | ans=='y')&&(msqid=msgget(key,msgflg))==-1))
{perror(“msgget”);
出口(1);
}
其他的
fprintf(stderr,“msgget:msgget successed:msqid=%d\n”,msqid);
而(ans=='y'| ans=='y')
{
printf(“\n1.自动数据\n2.输入数据\n3.退出\n输入您的选择\t”);
scanf(“%d”和“ch”);
getchar();
开关(ch)
{
案例自动:len=strlen(“你收到这个了吗?”);
sbuf=malloc(len+sizeof(int));
memset(sbuf,0,sizeof(message_buf));
sbuf->m=malloc(len+sizeof(int));
memset(sbuf->m,0,sizeof(msg1));
sbuf->m->msglen=len;
sbuf->m->cp=malloc(sizeof(len));
strncpy(sbuf->m->cp,“你得到这个了吗?”,strlen(“你得到这个了吗?”);
sbuf->m->cp[strlen(sbuf->m->cp)]='\0';
打破
案例用户数据:printf(“\n输入数据\t”);
fflush(stdout);
len=getline(&data,&msgsize,stdin);
sbuf=malloc(len+sizeof(int));
memset(sbuf,0,sizeof(message_buf));
sbuf->m=malloc(len+sizeof(int));
memset(sbuf->m,0,sizeof(msg1));
strcpy(sbuf->m->cp,数据);
sbuf->m->cp[strlen(sbuf->m->cp)]='\0';
sbuf->m->msglen=len;
打破
案例3:msgctl(msqid,IPC_RMID,NULL);
printf(“\n删除了q id=%d的队列,\n”,msqid);
出口(1);
默认值:printf(“\n再次尝试\t”);
scanf(“%c”和“&ans”);
getchar();
}
printf(“\nmsglen=%d\nmsgcp=%s”,sbuf->m->msglen,sbuf->m->cp);
/*发送消息*/
sbuf->mtype=1;
if(msgsnd(msqid,sbuf,2*sizeof(int),0)<0)
{
printf(“Msg q id=%d\nMsg type=%d\nMsg Text%s\nMsg Len=%d\n”,msqid,sbuf->mtype,sbuf->m->cp,sbuf->m->msglen);
perror(“msgsnd”);
出口(1);
}
其他的
printf(“\n消息:%s\n已发送\n”,sbuf->m->cp);
}
msgctl(msqid,IPC_RMID,NULL);
printf(“\n删除了q id=%d的队列,\n”,msqid);
返回0;
}
现在接收代码

//header files
#include"msgbuf.h"
int main()
{
    int msqid;
    key_t key;
    int msgflg = 0666;
    message_buf  *rbuf;
    int msg_len_rcvd=0;

    rbuf=malloc(150);
    rbuf->m=malloc(100);
    key = ftok("/home/user",15);
    if ((msqid = msgget(key, msgflg)) ==-1)
    {
            perror("msgget");
            exit(1);
    }
    printf("\n\n%d\n",msqid);
    /* Receive an answer of message type 1.   */
    while(1)
    {
            if ( (msg_len_rcvd=msgrcv(msqid, rbuf, 2*sizeof(int), 1, 0)) < 0)
            {
                    perror("msgrcv");
                    exit(1);
            }
            else
            {
                    printf("\n Number of bytes received:: %d", msg_len_rcvd);
                    printf("\nmtype1 = %d",rbuf->mtype);
                    printf("\nmsglen= %d",rbuf->m->msglen);
            }
            break;
    }
    return 0;
}
//头文件
#包括“msgbuf.h”
int main()
{
int msqid;
钥匙(t)钥匙;;
int msgflg=0666;
消息_buf*rbuf;
int msg_len_rcvd=0;
rbuf=malloc(150);
rbuf->m=malloc(100);
key=ftok(“/home/user”,15);
如果((msqid=msgget(key,msgflg))=-1)
{
佩罗尔(“msgget”);
出口(1);
}
printf(“\n\n%d\n”,msqid);
/*接收消息类型为1的应答*/
而(1)
{
如果((msg_len_rcvd=msgrcv(msqid,rbuf,2*sizeof(int),1,0))<0)
{
perror(“msgrcv”);
出口(1);
}
其他的
{
printf(“\n接收的字节数::%d”,msg\u len\u rcvd);
printf(“\nmtype1=%d”,rbuf->mtype);
printf(“\nmsglen=%d”,rbuf->m->msglen);
}
打破
}
返回0;
}

您正在发送一条包含指向message1结构的指针的消息。接收进程取消对该指针的引用,但在该进程中它并不指向同一事物。事实上,我很惊讶你没有犯错误

您应该这样定义msgbuf:

typedef struct msgbuf
{
    long    mtype;
    msg1    m;
} message_buf;
因此,msg1结构包含在msgbuf中,而不是由它指向


另外,您需要指定的大小是sizeof(message_buf),而不是sizeof(int)。

调用
msgrcv()
后的
errno
值是多少?接收的字节数。对不起,我用适当的问题更新了我的注释。errno值是多少?请在您正在打印的发送过程中显示整个代码
rbuf->m->msglen
-这不应该是sbuf,您刚才发送的消息吗?两个过程在同一台机器上。我是一名学生,所以我只是在尝试。我之所以选择sizeof(int),是因为我想先接收消息的长度,这样我就可以在接收过程中为cp分配空间,然后再接收cp。@user3436838它们是否在同一台机器上并不重要。不同的进程无法访问彼此的内存。谢谢先生。它起作用了。但问题是:我首先希望发送成功的msglen,然后希望发送cp。我已经为cp分配了空间,如rbuf->m.cp=malloc(rbuf->m.ms)
typedef struct msgbuf
{
    long    mtype;
    msg1    m;
} message_buf;