I'm writing a basic server program which has to receive two types of messages from clients (first message is of type 1 and second is of type 2). It seems that it doesn't see messeges from clients that have been sent properly (msgsnd doesn't return -1). I read that it may be caused by too big message, but my messages are like a few characters long and my buffer is 100. I didn't find any differences in structures I create, msgget also doesn't return any error. Here's the server program code:
struct msgbuf
{
long type;
char text[100];
}m1;
int main()
{
int id;
if (id = msgget(1998,0666|IPC_EXCL)==-1) {
printf("msgget error");
}
char first_msg[100][100];
char second_msg[100][100];
int counter = 0;
while (counter < 100) {
msgrcv(id,&m1,sizeof(m1.text),1,0);
printf("%s",m1.text);
strcpy(first_msg[counter], m1.text);
msgrcv(id,&m1,sizeof(m1.text),2,0);
printf("%s",m1.text);
strcpy(second_msg[counter],m1.text);
counter++;
}
return 0;
}
And a client code:
struct msgbuf
{
long type;
char text[100];
};
int main()
{
struct msgbuf m1,m2;
int id;
if ((id = msgget(1998,0666|IPC_EXCL)) == -1) {
printf("error");
}
char first_msg[90];
scanf("%s",&first_msg[0]);
char second_msg[90];
scanf("%s",&second_msg[0]);
m1.type = 1;
strcpy(m1.text,first_msg);
if (msgsnd(id,&m1,sizeof(m1.text),0) == -1) {
perror("msgsnd failed");
}
m2.type = 2;
strcpy(m2.text,second_msg);
if (msgsnd(id,&m2,sizeof(m2.text),0)==-1) {
perror("msgsnd2 failed");
}
return 0;
}
This is a nasty bug caused by an operator precedence problem.
In client, you have correctly written:
if ((id = msgget(1998,0666|IPC_EXCL)) == -1) {
and parens ensure that you first assign to id
and then compare to -1.
But in server, you only have:
if (id = msgget(1998,0666|IPC_EXCL)==-1) {
Unfortunately it actually reads if (id = (msgget(1998,0666|IPC_EXCL)==-1))
, because the comparison has higher precedence than the assignment!
The fix is trivial: just add parens in server.c as they are in client.c