Search code examples
clinuxipcmessage-queuemsgrcv

Message receive program only printing every other message


I am have implemented the two programs from section 7.6 of http://beej.us/guide/bgipc/output/html/multipage/mq.html.

I have extended it so that there are two receiving programs and which one it goes to is determined by the message type.

The problem arises in the receiving program, B and C. They are supposed to print out the messages entered into program A everytime, however they only print the messages every other time.

This is where the message is sent, it reads the first 6 chars and if it is URGENT it sets the the message type.

buf.mtype = 2;

while(fgets(buf.mtext, sizeof buf.mtext, stdin) != NULL) {
        int len = strlen(buf.mtext);

        strncpy(typeTest, buf.mtext, 6);

        if(strncmp(typeTest, "URGENT", 6) == 0){
            buf.mtype = 1;
        }       

        printf("This is the message %s \n", buf.mtext);

        /* ditch newline at end, if it exists */
        if (buf.mtext[len-1] == '\n') buf.mtext[len-1] = '\0';

        if (msgsnd(msqid, &buf, len+1, 0) == -1) /* +1 for '\0' */
            perror("msgsnd");
    }

This is where the message is received, then the if statement checks the type to then print out.

for(;;) { /* Spock never quits! */
        if (msgrcv(msqid, &buf, sizeof buf.mtext, 0, 0) == -1) {
            perror("msgrcv");
            exit(1);
        }

        if(buf.mtype == 2){
            printf("spock: \"%s\"\n", buf.mtext);
        }
    }

Can anyone shed some light on why it only prints out every other message?

Thanks.


Solution

  • In your program A you must set buf.mtype to 2 if the input is not "URGENT..." You must do that in the loop, every time.

    while(fgets(buf.mtext, sizeof buf.mtext, stdin) != NULL) {
        int len = strlen(buf.mtext);
    
        strncpy(typeTest, buf.mtext, 6);
    
        if(strncmp(typeTest, "URGENT", 6) == 0){
            buf.mtype = 1;
        }       
        else buf.mtype= 2;    // always set the default
    
        printf("This is the message %s \n", buf.mtext);
    
        /* ditch newline at end, if it exists */
        if (buf.mtext[len-1] == '\n') buf.mtext[len-1] = '\0';
    
        if (msgsnd(msqid, &buf, len+1, 0) == -1) /* +1 for '\0' */
            perror("msgsnd");
    }
    

    In your programs B and C you must set msgtyp to 1 or 2 for each program to get the right message from the queue, for example:

    int main(argc, argv)
    {
        int msgtype;
        if (*argv[1]=='A')
            msgtype= 1;
        else if (*argv[1]=='B')
            msgtype= 2;
        else
            msgtype= 0;
        ...
        for(;;) { /* Spock never quits! */
            if (msgrcv(msqid, &buf, sizeof buf.mtext, msgtype, 0) == -1) {
                perror("msgrcv");
                exit(1);
            }
    
            if(buf.mtype == msgtype){
                printf("spock: \"%s\"\n", buf.mtext);
            }
        }
        return 0;
    }