消息队列多接收器实现

时间:2014-04-01 20:58:22

标签: c message-queue

广播节目是这样的。我使用了3个不同的按键,但只有第一个听众收到消息。其他人收到消息发送错误。按键应该识别不同的用户不应该? ?

#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 个答案:

答案 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_key更改为send_key1,第三行更改send_keysend_key3

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

  

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

因此,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来电的返回代码。您应该检查所有三个的返回码,以确保那里没有问题。