Ошибка: неверный аргумент; при отправке сообщения msgsnd(); не совпадает идентификатор очереди

Я только изучал IPC на Linux и придумал три простые программы. Один предназначен для создания (и администрирования в функции) очереди сообщений. Второй должен просто отправить сообщение в очередь, созданную первым. Третья программа получает данные из очереди.

Все программы наследуются из одного корневого каталога и разбиваются на отдельные каталоги для каждого источника и двоичных файлов.

Так что давайте просто сосредоточимся на создании и отправке части, и это поможет мне исправить и третью программу.

добавить очередь main.c:

#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <errno.h>
#include <sys/ipc.h>
#include <sys/msg.h>

#define FAILED -1


int main(int argc, char *argv[]) {
  // message data
  key_t key;
  int msgqid;

  if ((key = ftok("../src/main.c", 'Z')) == FAILED) {
    perror("ftok");
    exit(1);
  }

  if ((msgqid = msgget(key, 0666 | IPC_CREAT)) == FAILED) { /* create an message queue with owner & group & others permission set to rw- */
    perror("msgget");
    exit(1);
  }

  printf("Message Queue %i with key %i, been created [press return to delete]", msgqid, key);
  getchar();

  if (msgctl(msgqid, IPC_RMID, NULL) == FAILED) {
    perror("msgctl");
    exit(1);
  }
  printf("I'm outta here! \n");

  return 0;
}

отправить main.c:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/msg.h>
#include <stddef.h>
#include <string.h>

#include "../../lib/shared_msgbuf.h" /* mbuf, MSGSZ */

#define FAILED -1


int main(void) {
  char s[MSGSZ];

  printf("Enter a message: ");

  if (fgets(s, sizeof s, stdin) == NULL)
    perror("fgets");
  else 
    strcpy(mbuf.mtext, s);

  printf("Connecting to the queue... \n", s);

  // Setup
  key_t key;
  int msgqid;

  if ((key = ftok("../../adqueue/src/main.c", 'Z')) == FAILED) {
    perror("ftok");
    exit(1);
  }

  if (msgqid = msgget(key, 0666) == FAILED) {
    perror("msget");
    exit(1);
  }

  printf("\n*CONNECTION ESTABLISHED* \n");
  printf("queue id: %i \n", msgqid);
  printf("queue key: %d \n", key);
  printf("message: %s \n", s);

  printf("Sending the message... \n");
  if (msgsnd(msgqid, &mbuf, MSGSZ, 0) == FAILED) {
    perror("msgsnd");
    exit(0);
  }

  return 0;
}

Так что проблема в том, что я получаю Invalid argument номер ошибки при попытке отправить сообщение. Глядя на данные, я не могу понять, почему идентификатор не совпадает, так как подключение к очереди, кажется, работает...

Примерные данные:

./cadqueue 
Message Queue 327680 with key 1510081535, been created [press return to delete]

./send 
Enter a message: test
Connecting to the queue... 

*CONNECTION ESTABLISHED* 
queue id: 0 
queue key: 1510081535 
message: test

Sending the message... 
msgsnd: Invalid argument

2 ответа

Решение

Ваша ошибка исходит из этой строки:

if (msgqid = msgget(key, 0666) == FAILED) {

Так должно быть

if ((msgqid = msgget(key, 0666)) == FAILED) {

В первом случае из-за приоритета оператора сравнение (==) делается до назначения (=).

Во втором случае paranthesis сообщает компилятору, что нужно сделать в первую очередь.

Это заголовочные файлы, необходимые для msgsnd()

   #include <sys/types.h>
   #include <sys/ipc.h>
   #include <sys/msg.h>

В опубликованном коде для переносимости отсутствует два из этих заголовочных файлов, включающих операторы

===========

это утверждение:

if (msgqid = msgget(key, 0666) == FAILED) {

отсутствует IPC_CREAT это должно быть частью 0666 параметр

===========

mbuf имеет два поля, mtype поле, которое ДОЛЖНО быть положительным, > 0 и mtext поле.

Размещенный код устанавливает mtext поле, но не в состоянии установить mtype поле.

=============

это утверждение:

printf("Connecting to the queue... \n", s);

проблема в том, что есть входной параметр, но у них нет спецификатора формата в "строке формата"

============

key значение должно быть одинаковым для каждого доступа к одной и той же очереди сообщений.

поэтому звонки ftok() должны иметь один и тот же параметр, иначе они будут генерировать разные / уникальные очереди сообщений через вызов msgget()

============

Примечание: очереди сообщений не исчезают только потому, что программа завершается. Поэтому управляющая программа (или последний пользователь последнего сообщения) должна вызывать msgctl() удалить очередь сообщений

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