2014-04-01 110 views
0

的广播节目this.I使用了3分不同的密钥,但只有第一个监听获取其他message.the我们得到消息发送和error.The键应该识别不同的用户应该不会吧?消息队列mutilple接收机实现

#include <stdio.h> 
#include <stdlib.h> 
#include <errno.h> 
#include <string.h> 
#include <sys/types.h> 
#include <sys/ipc.h> 
#include <sys/msg.h> 
#include <pthread.h> 

struct msgbuf 
{ 
long mtype; 
char mtext[140]; 
}send_buf,recv_buf; 

int send_msg_id,send_msg_id1,send_msg_id2; 
key_t send_key,send_key1,send_key2; 

int main() 
{ 
send_key=ftok("broadcast.c",'A'); 
send_key1=ftok("broadcast.c",'B'); 
send_key2=ftok("broadcast.c",'C'); 
char save[140]; 
if (send_key==-1) 
{ 
    perror("\nCaller send key error(ftok)"); 
    exit(1); 
} 
send_msg_id=msgget(send_key,0666 | IPC_CREAT); 
send_msg_id1=msgget(send_key,0555 | IPC_CREAT); 
send_msg_id2=msgget(send_key,0777 | IPC_CREAT); 
if (send_msg_id==-1) 
{ 
    printf("\nCaller send msgget error"); 
    exit(1); 
} 
printf("\nCALLER:"); 
while (fgets(send_buf.mtext,sizeof(send_buf.mtext),stdin)!=NULL) 
{ 
    send_buf.mtype=1; 
    int len=strlen(send_buf.mtext); 
    strcpy(save,send_buf.mtext); 
    if (send_buf.mtext[len-1]=='\n'); 
     send_buf.mtext[len-1]='\0'; 
    if (msgsnd(send_msg_id,&send_buf,len+1,0)==-1) 
     printf("\nMsg sending error\n"); 
    strcpy(send_buf.mtext,save); 
    if (msgsnd(send_msg_id1,&send_buf,len+1,0)==-1) 
     perror("\nMsg sending error (send_msg_id1)"); 
    strcpy(send_buf.mtext,save); 
    if (msgsnd(send_msg_id2,&send_buf,len+1,0)==-1) 
     perror("\nMsg sending error (send_msg_id2)"); 
} 
int i=0; 
while(i<9999) 
    i++; 
msgctl(send_msg_id,IPC_RMID,NULL); 
return 0; 
} 

回答

1

我在审查代码时发现了一些可能的问题。

首先,你叫msgget()三次。每次使用存储在变量send_key相同的密钥。我相信这个代码应该是:

send_msg_id= msgget(send_key, 0666 | IPC_CREAT); 
send_msg_id1=msgget(send_key1, 0555 | IPC_CREAT); 
send_msg_id2=msgget(send_key2, 0777 | IPC_CREAT); 

注意在第二行send_keysend_key1send_keysend_key3在第三行的变化。

其次,值0666,05550777表示消息队列的权限。如msgget()手册页所述:

创建后,参数msgflg的最低位将定义消息队列的权限。作为指定的开放模式参数的权限这些权限位具有相同的格式和语义(2)。 (不使用的执行权限。)

因此,0666给出读/写权限的所有,0555给出读取权限所有,并0777给出读/写权限的所有(如所指出的执行位被忽略在手册页中)。这可能不是你的意图。最简单的变化将是使所有这些0666进行读/写(或0600,如果你想限制只访问你的用户)。 0555将是一个问题,因为它是只读的。所以,上面的进一步变更为:

send_msg_id= msgget(send_key, 0666 | IPC_CREAT); 
send_msg_id1=msgget(send_key1, 0666 | IPC_CREAT); 
send_msg_id2=msgget(send_key2, 0666 | IPC_CREAT); 

第三,你只检查返回代码为先ftokmsgget电话。您应该检查所有三个代码的返回码,以确保这里没有问题。