Ошибка в msgrcv(): получение данных через очередь сообщений в C

Я отправляю сообщение, используя механизм очереди сообщений в C linux. Но есть некоторая проблема с функцией msgrcv. Это показывает ошибку как неверный аргумент. Пожалуйста, проверьте это.

//msgrcv.c
#include"msgbuf.h"
int main()
{
      int msqid;
      key_t key;
      message_buf  *rbuf;
      rbuf=malloc(sizeof(*rbuf));
     // rbuf->m=malloc(sizeof(M1));

      key = ftok("/home/user",'a');
      if ((msqid = msgget(key, IPC_CREAT)) ==(key)-1)
      {
         perror("msgget");
         exit(1);
      }

      /* Receive an answer of message type 1.   */
      if (msgrcv(msqid, &rbuf, sizeof(rbuf->m), 1, 0) < 0)
      {
           perror("msgrcv");  //invalid argument to msgrcv
           exit(1);
       }
         /* Print the answer.  */
       printf("Received message text= %s\n", rbuf->m.cp);
      return 0;
   }

сейчас msgbuf.h

 //msgbuf.h
typedef struct msgclient
{
   int msglen;
   int msgtype;
   char *cp;
}M1;

typedef struct msgbuf1
{
   long    mtype;
   M1      m;
} message_buf;

Я также хотел бы знать, как происходит двусторонняя связь с использованием очереди сообщений. Нужно ли создавать две очереди сообщений, чтобы установить связь между двумя процессами? Пример кода для того же приветствуется.

Спасибо:)

2 ответа

Решение

Я думаю это

if ((msqid = msgget(key, 0666)) ==key-1)

должно быть

if ((msqid = msgget(key, 0666)) == -1)

От msgrcv

ОШИБКИ
Функция msgrcv() завершится ошибкой, если:
...
[EINVAL]
msqid не является допустимым идентификатором очереди сообщений.

Более того, message_buf.m не должен быть указателем, а членом

typedef struct msgbuf1
{
   long    mtype;
   M1      m;
} message_buf;

Затем вы можете сохранить этот вызов malloc

rbuf->m=malloc(sizeof(M1));

и призыв к msgrcv должно быть

if (msgrcv(msqid, rbuf, sizeof(rbuf->m), 1, 0) < 0)

потому что иначе msgrcv перезапишет ваш стек.

Обновить:

От msgget

ОШИБКИ
[ENOENT]
Идентификатор очереди сообщений не существует для ключа аргумента, и (msgflg & IPC_CREAT) равен 0.

Это означает, что вы должны позвонить

if ((msqid = msgget(key, IPC_CREAT | 0666)) == -1)

по крайней мере, в первый раз вы вызываете эту функцию.

Я уже вижу одну серьезную проблему:

message_buf  *rbuf;
rbuf=malloc(sizeof(rbuf));

поскольку rbuf это указатель, вы должны использовать

rbuf=malloc(sizeof(*rbuf));

Ваш оригинал дает вам размер указателя (обычно четыре или восемь байтов в текущих компиляторах), а не размер message_buf структура, которая вам нужна.

Другая проблема - ваше сравнение с key-1 который я считаю, должен быть (key)-1,

Возможно, что ваш msgget не удается, и из-за этой ошибочной проверки вы его не обнаруживаете. Это означает, что msgrecv будет использовать -1 в качестве идентификатора очереди, объясняя сбой там.

Другие вопросы по тегам