广播节目是这样的。我使用了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;
}
答案 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_key
至send_key3
。
其次,值0666
,0555
和0777
表示消息队列的权限。如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);
第三,您只需检查首次ftok
和msgget
来电的返回代码。您应该检查所有三个的返回码,以确保那里没有问题。