Mq_receive: message is too long

I implement a relationship between two processes using a queue. The problem is that when I call the mq_receive function, I get this error: the message is too long.

I have done the following:

struct mq_attr attr; long size = attr.mq_msgsize; .... // initializing the queue "/gateway" int rc = mq_receive(gateway, buffer, size, &prio); 

If I print the size value, I get size = 1, and when I print the same size, but from a different program (obtained by the same mechanism), I get something not a long integer (-1217186280) ...

How can I solve this error? .... so long as size = 1, I think it’s right to say “message too long”, but why 1?

PS I also tried to put:

 int rc = mq_receive(gateway, buffer, sizeof(buffer), &prio); 

but without result.

+6
source share
3 answers

Sounds like you need to read the documents carefully. When you call mq_receive , you must pass the size of the destination buffer. This size must be larger than the queue mq_msgsize attribute . Also, it looks like you have an error in initializing the attributes of the queue, which makes the correct call to mq_receive impossible. Here is a standard message queue session:

  • Fill mq_attr struct ( doc ):

     struct mq_attr attr; attr.mq_flags = 0; attr.mq_maxmsg = 10; attr.mq_msgsize = 33; attr.mq_curmsgs = 0; 
  • Create a queue with mq_open in the main process ( doc ):

     mqd_t queue = mq_open(qname, O_CREAT|O_RDWR, 0644, &attr); 
  • In the process of recording scripts for recording:

     mqd_t queue = mq_open(qname, O_WRONLY); 

    And send the text. The length of the text should be less than the mq_msgsize attribute of the queue ( doc ):

     mq_send(queue, "some message", strlen("some message")+1, 1); 
  • While reading, read the read queue:

     mqd_t queue = mq_open(qname, O_RDONLY); 

    And then allocate a buffer and receive a message. The buffer * must be larger than the queue mq_msgsize attribute. Here we create a 50-byte buffer, and mq_msgsize == 33 ( doc ):

     char rcvmsg[50]; int iret = mq_receive(queue, rcvmsg, 50, NULL); 

Also remember that you must use %ld to print long instead of %d .

+17
source

When debugging POSIX queues in real time, you should start with an example program that runs and moves from there. Once you have the sample program running, it should just be sure that your own code follows all the steps.

The following program was successfully tested in Ubuntu 11.04:

 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <mqueue.h> #define MQNAME "/pax" #define MQMESG "Hello there!" static mqd_t serverUp (void) { int rc; mqd_t svrHndl; struct mq_attr mqAttr; printf ("Bringing up server.\n"); rc = mq_unlink (MQNAME); if (rc < 0) { printf (" Warning %d (%s) on server mq_unlink.\n", errno, strerror (errno)); } mqAttr.mq_maxmsg = 10; mqAttr.mq_msgsize = 1024; svrHndl = mq_open (MQNAME, O_RDWR|O_CREAT, S_IWUSR|S_IRUSR, &mqAttr); if (svrHndl < 0) { printf (" Error %d (%s) on server mq_open.\n", errno, strerror (errno)); exit (1); } printf (" Server opened mqd_t of %d.\n", svrHndl); return svrHndl; } static void serverReceive (mqd_t svrHndl) { int rc; char buffer[2048]; printf ("Server receiving on mqd_t %d.\n", svrHndl); rc = mq_receive (svrHndl, buffer, sizeof (buffer), NULL); if (rc < 0) { printf (" Error %d (%s) on server mq_receive.\n", errno, strerror (errno)); exit (1); } printf (" Received [%s].\n", buffer); } static void serverDown (mqd_t svrHndl) { printf ("Bringing down server with mqd_t %d.\n", svrHndl); mq_close (svrHndl); } static void clientSend (void) { mqd_t cliHndl; int rc; printf ("Client sending.\n"); cliHndl = mq_open (MQNAME, O_RDWR); if (cliHndl < 0) { printf (" Error %d (%s) on client mq_open.\n", errno, strerror (errno)); exit (1); } printf (" Client opened mqd_t of %d.\n", cliHndl); rc = mq_send (cliHndl, MQMESG, sizeof (MQMESG), 1); if (rc < 0) { printf (" Error %d (%s) on client mq_send.\n", errno, strerror (errno)); exit (1); } mq_close (cliHndl); } int main (void) { mqd_t svrHndl; svrHndl = serverUp (); clientSend (); serverReceive (svrHndl); serverDown (svrHndl); return 0; } 

The output on my system is:

 Bringing up server. Server opened mqd_t of 3. Client sending. Client opened mqd_t of 4. Server receiving on mqd_t 3. Received [Hello there!]. Bringing down server with mqd_t 3. 
+6
source

Remember to disable the message queue before starting your program again. If you do not disconnect it, it will still use the old message queue settings. This happens when you end your program with Ctrl + C. I think it’s nice to put the following code at the beginning of the program:

 if(mq_unlink(QUEUENAME) == 0) fprintf(stdout, "Message queue %s removed from system.\n", QUEUENAME); 

An alternative form (C ++ style) that checks for real errors (e.g. permissions) and ignores cases where the queue already exists or not:

 int rc = mq_unlink(name.c_str()); if (rc != 0 && errno != ENOENT) THROW_ERRNO_EXCEPTION(); // ENOENT is the status code if the queue doesn't exist, which is not an error // if you are immediately going to create it. 
+5
source

Source: https://habr.com/ru/post/885671/


All Articles