Ошибка: неверный аргумент; при отправке сообщения 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()
удалить очередь сообщений