msgsnd与msgrcv函数出现invalid参数的问题

本文转自:http://www.cppblog.com/lmlf001/archive/2007/09/19/32486.html

 

今天写了一个小程序,使用了消息队列的msgsnd msgrcv函数,由msgsnd函数循环处理由终端输入的消息,然后把它发送到消息队列,而另一个进程则循环读取消息,进行处理。
    这时,问题出现了,每次调用msgrcv函数的时候,它总是第一次调用成功,而第二次返回错误,察看errno=22,打印出来是invalid argument,无效参数。
    凭它的说明,可以看出可能是我调用函数的时候参数错误,但为什么第一次能调用成功呢?
    检查了一下,没看出问题。然后google之,发现许多人和我出现了同样的问题,但没有人给出解答。
    自己鼓捣了好久,还是没搞定。
    然后man 2 msgsnd,一下午不知打了多少遍了,这一次从头到尾一个字一个字的读了下去。
    终于发现问题了。

    int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);

    ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);


man文档里有一句话:The  mtext  field  is an array (or other structure) whose size is specified by msgsz  
    一直没认真去看,想当然的以为msgsz就是msgp的大小了,原来人家不是,自己自作多情了。。。

    这么一个小问题花了我半个下午,但现在发现总比以后出错要好多了~ 
    写出来,给那些第一次使用的朋友们看~~
   
    把修改后的代码贴出来:

struct s_msg{
    long type;
    char mtext[256];
};


 

//snd
int main()
{
    int mid;
    if((mid=msgget(4446,IPC_CREAT|0666))==-1)
        perr_exit("msgget:");
    char buf[BUFSIZE];
    memset(buf,'\0',BUFSIZE);
    s_msg mymsg;
    while(fgets(buf,BUFSIZE,stdin)!=NULL){
        if(strlen(buf)<=2)continue;
        buf[strlen(buf)]='\0';
        if(sscanf(buf,"%d%s",&mymsg.type,mymsg.mtext)!=2)
            perr_exit("Invalid input:");
        if(msgsnd(mid,&mymsg,256,IPC_NOWAIT))      //msgsiz 为sizeof(mtext[]),而非sizeof(s_msg)
            perr_exit("msgsnd:");
        memset(buf,'\0',BUFSIZE);
    }
    return 0;
}


 

//rcv
int main(int argc,char **argv)
{
    int mid;
    if((mid=msgget(4446,IPC_CREAT|0666))==-1)
        perr_exit("msgget:");
    s_msg mymsg;
    while(1)
    {
        if(msgrcv(mid,&mymsg,256,0,MSG_NOERROR)==-1)   //就是这里出错的,记住你了
                perr_exit("msgrcv");
        if(mymsg.type!=4446)
            cout<<mymsg.type<<" :"<<mymsg.mtext<<endl;
        else {
            cout<<"4446 quit\n";
            break;    
        }
        memset(&mymsg,0,sizeof(mymsg));
    }
    return 0;
}


 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值