Search code examples
clinuxipcmqueue

How do I use mqueue in a c program on a Linux based system?


How do I use mqueue (message queue) in a c program on a Linux based system?

I'm looking for some good code examples that can show how this is done in a correct and proper way, maybe a howto.


Solution

  • The following is a simple example of a server that receives messages from clients until it receives an "exit" message telling it to stop.

    The code for the server:

    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <sys/stat.h>
    #include <sys/types.h>
    #include <errno.h>
    #include <mqueue.h>
    
    #include "common.h"
    
    int main(int argc, char **argv)
    {
        mqd_t mq;
        struct mq_attr attr;
        char buffer[MAX_SIZE + 1];
        int must_stop = 0;
    
        /* initialize the queue attributes */
        attr.mq_flags = 0;
        attr.mq_maxmsg = 10;
        attr.mq_msgsize = MAX_SIZE;
        attr.mq_curmsgs = 0;
    
        /* create the message queue */
        mq = mq_open(QUEUE_NAME, O_CREAT | O_RDONLY, 0644, &attr);
        CHECK((mqd_t)-1 != mq);
    
        do {
            ssize_t bytes_read;
    
            /* receive the message */
            bytes_read = mq_receive(mq, buffer, MAX_SIZE, NULL);
            CHECK(bytes_read >= 0);
    
            buffer[bytes_read] = '\0';
            if (! strncmp(buffer, MSG_STOP, strlen(MSG_STOP)))
            {
                must_stop = 1;
            }
            else
            {
                printf("Received: %s\n", buffer);
            }
        } while (!must_stop);
    
        /* cleanup */
        CHECK((mqd_t)-1 != mq_close(mq));
        CHECK((mqd_t)-1 != mq_unlink(QUEUE_NAME));
    
        return 0;
    }
    

    The code for the client:

    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <sys/stat.h>
    #include <sys/types.h>
    #include <mqueue.h>
    
    #include "common.h"
    
    
    int main(int argc, char **argv)
    {
        mqd_t mq;
        char buffer[MAX_SIZE];
    
        /* open the mail queue */
        mq = mq_open(QUEUE_NAME, O_WRONLY);
        CHECK((mqd_t)-1 != mq);
    
    
        printf("Send to server (enter \"exit\" to stop it):\n");
    
        do {
            printf("> ");
            fflush(stdout);
    
            memset(buffer, 0, MAX_SIZE);
            fgets(buffer, MAX_SIZE, stdin);
    
            /* send the message */
            CHECK(0 <= mq_send(mq, buffer, MAX_SIZE, 0));
    
        } while (strncmp(buffer, MSG_STOP, strlen(MSG_STOP)));
    
        /* cleanup */
        CHECK((mqd_t)-1 != mq_close(mq));
    
        return 0;
    }
    

    The common header:

    #ifndef COMMON_H_
    #define COMMON_H_
    
    #define QUEUE_NAME  "/test_queue"
    #define MAX_SIZE    1024
    #define MSG_STOP    "exit"
    
    #define CHECK(x) \
        do { \
            if (!(x)) { \
                fprintf(stderr, "%s:%d: ", __func__, __LINE__); \
                perror(#x); \
                exit(-1); \
            } \
        } while (0) \
    
    
    #endif /* #ifndef COMMON_H_ */
    

    Compiling:

    gcc -o server server.c -lrt
    gcc -o client client.c -lrt