struct msgbuf {
long mtype;
char mtext[1];
};
书中说明这个结构体我们可以自己定义。然后给出例子:
#define MY_DATA 8
typedef struct my_msfbuf
{
long
int16_t mshort;
char mchar[MY_DATA];
}Message;
struct mymesg
{
long type;
long len;
char data[SIZE];
};
运行结果每次输入的都少4个字长,然后我man了一下这个函数,说是mtext可以使用其他数据类型,然后我想当然的认为:只能改变mtext的数据类型不能增加成员变量。但是今天我又重新试了一下用
struct m
{
};
struct mymesg
{
long type;
struct m me;
};
刚开始我传的是type的地址即&mesg.type结果还是和上面的结果一样,然后我改为传&mesg,msgsnd返回为-1,检查错误说是参数无效,然后查了好多这方面的原因无果,我突然想起来书上在给出上面那个结构体例子后貌似有这样一句话:msgsnd的length参数以字节为单位指定待发送消息的长度。这是位于长整数消息类型之后的用户自定义数据的长度。该长度可以是0。上例中的长度可以传递成sizeof(Message)-sizef(long)。意思就是除了long类型的type外剩下的长度都是我们的消息长度,我们的msgrcv函数返回的字节数也是那样,注意一定是除type长度以外的其他成员变量的总长度。我最初时一直认为是你输入字符串的长度,其实不然。(这个问题纠结了我好几天,现在终于弄清楚了)
#include<stdio.h>
#include<string.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<unistd.h>
#define SIZE 100
#define key1 123
#define key2 234
struct m
{
};
struct mymesg
{
long type;
struct m me;
};
int main()
{
long len;
ssize_t n;
int readfd,writefd;
struct mymesg mesg;
readfd=msgget(key1,IPC_CREAT|0666);
writefd=msgget(key2,IPC_CREAT|0666);
mesg.type=1;
n=msgrcv(readfd,&mesg,SIZE,mesg.type,0);
write(STDOUT_FILENO,mesg.me.data,n);
printf("\n");
printf("plase input message:\n");
fgets(mesg.me.data,SIZE,stdin);
mesg.me.len=strlen(mesg.me.data);
len=mesg.me.len +sizeof(long);
msgsnd(writefd,&mesg, len,0);
system("ipcs -q");
return 0;
}
#include<stdio.h>
#include<string.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<unistd.h>
#define SIZE 100
#define key1 123
#define key2 234
struct m
{
};
struct mymesg
{
long type;
struct m me;
};
int main()
{
long len;
ssize_t n;
int readfd,writefd;
struct mymesg mesg;
writefd=msgget(key1,0);
readfd=msgget(key2,0);
mesg.type=1;
printf("plase input message:\n");
fgets(mesg.me.data,SIZE,stdin);
mesg.me.len=strlen(mesg.me.data);
len=mesg.me.len +sizeof(long);
msgsnd(writefd,&mesg, len,0);
n=msgrcv(readfd,&mesg,SIZE,mesg.type,0);
printf("n=%d,len=%d",n,mesg.me.len);
write(STDOUT_FILENO,mesg.me.data,n);
system("ipcs -q");
msgctl(readfd,IPC_RMID,NULL);
msgctl(writefd,IPC_RMID,NULL);
return 0;