我在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;
答案 0 :(得分:1)
您正在发送一条消息,其中包含指向您的message1结构的指针。接收进程取消引用该指针,但在该进程中它不指向同一个东西。事实上,我很惊讶你没有得到段错误。
您应该像这样定义msgbuf:
typedef struct msgbuf
{
long mtype;
msg1 m;
} message_buf;
因此msg1结构包含在msgbuf中而不是由它指向。
此外,您需要指定的大小是sizeof(message_buf),而不是sizeof(int)。
答案 1 :(得分:0)
//header files
#include"msgbuf.h" //where I have put my structures
#define AUTOMATIC 1
#define USER_DATA 2
int main()
{
int msgflg = IPC_CREAT | 0666,ch,len=0;
size_t msgsize = 0;
int msqid;
key_t key;
message_buf *sbuf;
char ans;
char *data;
key = ftok("/home/user",15);
printf("Do you want to send messages\t");
scanf("%c",&ans);
getchar();
if (((ans=='y' || ans=='Y') && (msqid = msgget(key, msgflg )) ==-1))
{ perror("msgget");
exit(1);
}
else
fprintf(stderr,"msgget: msgget succeeded: msqid = %d\n", msqid);
while(ans=='y' || ans=='Y')
{
printf("\n1. Automatic data\n2. Enter data\n3. Exit\nEnter your choice\t");
scanf("%d",&ch);
getchar();
switch(ch)
{
case AUTOMATIC: len=strlen("Did you get this?");
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, "Did you get this?",strlen("Did you get this?"));
sbuf->m->cp[strlen(sbuf->m->cp)]='\0';
break;
case USER_DATA: printf("\nEnter data\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, data);
sbuf->m->cp[strlen(sbuf->m->cp)]='\0';
sbuf->m->msglen=len;
break;
case 3: msgctl(msqid, IPC_RMID, NULL);
printf("\nQueue with q id = %d is removed\n",msqid);
exit(1);
default:printf("\nTRY AGAIN\t");
scanf("%c",&ans);
getchar();
}
printf("\nmsglen = %d\nmsgcp= %s",sbuf->m->msglen,sbuf->m->cp);
/* Send a message */
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");
exit(1);
}
else
printf("\nMessage: %s\n Sent\n", sbuf->m->cp);
}
msgctl(msqid, IPC_RMID, NULL);
printf("\nQueue with q id = %d is removed\n",msqid);
return 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;
}