为什么我无法使用 msgrcv() 访问消息队列中的消息文本?
Why aren't I able to access the message text in my message queue using msgrcv()?
我构建了一个程序,允许我创建和删除消息队列以及发送和接收消息。
除了接收消息外,一切似乎都正常。当我收到结构时,我可以访问类型(我一直用它来表示 "recipient")并打印它,但是存储在结构的 msg 字段中的字符串不会打印。在使用 msgrcv() 之后,printf() 似乎成功访问了 mbuf.type 字段但没有访问 mbuf.msg。我试过调试找出问题出在哪里,但到目前为止我一直没有成功。
消息似乎已发送到队列中,因为当我使用 "ipcs -q" 查看内核的消息队列时,它会正确显示我已发送的消息数。我还能够访问和打印发送消息的程序实例中的 msg 字段。直到程序退出并使用“-r”标志重新启动程序后,我才无法打印 msg 字段。
我已经包含了下面的代码,包括包含我的消息结构定义的头文件。
请注意:我知道我的验证很笨拙,我计划在程序正常运行后对其进行简化。如果造成混淆,我深表歉意。
头文件:
#ifndef MESSAGE_BUFFER
#define MESSAGE_BUFFER
#define MSG_MAX 4056
typedef struct messageBuffer
{
long recipient; //recipient of message
long senderID; //id number of the sender
char msg[MSG_MAX]; //content of the message
}messageBuffer;
#endif
主线:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/types.h>
#include "message.h"
//function to print usage information upon error
void printUsage(){
printf("Error: Invalid arguments\n");
printf("Usage:\n");
printf("(Create Queue) <-c/C> <key>\n");
printf("(Send a message) <-s/S> <key> <recipient_id> <message>\n");
printf("(Receive a message) <-r/R> <key> <recipient_id>\n"); printf("(Delete queue) <-d/D> <key>\n");
}
//main
int main(int argc, char **argv){
//declare necessary variables
char flag;
int msqid;
messageBuffer mbuf;
size_t buf_length;
int msgflg = IPC_CREAT | 0666;
key_t key;
unsigned long recipient;
//validate arguments
if((argc < 3 || argc > 5) || argv[1][0] != '-' || strlen(argv[1]) != 2){
printf("%d\n", argc);
printUsage();
return -1;
}
flag = argv[1][1];
switch(flag){
//Create a message queue
case 'c':
case 'C':
if((key = atoi(argv[2])) < 1){
printf("Error assigning key");
return -1;
}
if((msqid = msgget(key, msgflg)) < 1){
printf("Error creating queue:");
return -1;
}
printf("%s%i\n", "Key: ", key);
printf("%s%i\n", "msqid: ", msqid);
break;
//Send a message
case 's':
case 'S':
if((key = atoi(argv[2])) < 1){
perror("Error assigning key:");
return -1;
}
if((msqid = msgget(key, 0400)) < 1){
perror("Error accessing queue:");
}
mbuf.recipient = atoi(argv[3]);
strncpy(mbuf.msg, argv[4], MSG_MAX);
buf_length = strlen(mbuf.msg) + 1;
if(msgsnd(msqid, &mbuf, buf_length, 0) < 0){
perror("Error sending message:");
return -1;
}
printf("Message sent (%lu): %s\n", mbuf.recipient, mbuf.msg);
break;
//Receive a message
case 'r':
case 'R':
if((key = atoi(argv[2])) < 1){
perror("Error assigning key:");
return -1;
}
if((msqid = msgget(key, 0400)) < 1){
perror("Error accessing queue:");
}
recipient = atoi(argv[3]);
if( msgrcv(msqid, &mbuf, MSG_MAX, recipient, 0)< 0){
perror("Error receiving message:");
return -1;
}
printf("Message received (%lu):\n", mbuf.recipient);
printf("%s\n", mbuf.msg);
break;
//Delete a message queue
case 'd':
case 'D':
if((key = atoi(argv[2])) < 1){
perror("Error assigning key");
return -1;
}
if((msqid = msgget(key, 0400)) < 1){
perror("Error accessing queue:");
}
printf("%d\n", msqid);
if((msgctl(msqid, IPC_RMID, NULL)) < 0){
perror("Delete message queue failed:");
}
break;
//invalid flag
default:
printUsage();
return -1;
}
return 0;
}
如有任何意见,我将不胜感激。谢谢。
事实证明问题出在指定正在传递的结构的大小上。我已将代码 "buf_length = strlen(mbuf.msg) + 1;" 更改为 buf_length = (sizeof(mbuf.msg) + 1);
我构建了一个程序,允许我创建和删除消息队列以及发送和接收消息。
除了接收消息外,一切似乎都正常。当我收到结构时,我可以访问类型(我一直用它来表示 "recipient")并打印它,但是存储在结构的 msg 字段中的字符串不会打印。在使用 msgrcv() 之后,printf() 似乎成功访问了 mbuf.type 字段但没有访问 mbuf.msg。我试过调试找出问题出在哪里,但到目前为止我一直没有成功。
消息似乎已发送到队列中,因为当我使用 "ipcs -q" 查看内核的消息队列时,它会正确显示我已发送的消息数。我还能够访问和打印发送消息的程序实例中的 msg 字段。直到程序退出并使用“-r”标志重新启动程序后,我才无法打印 msg 字段。
我已经包含了下面的代码,包括包含我的消息结构定义的头文件。
请注意:我知道我的验证很笨拙,我计划在程序正常运行后对其进行简化。如果造成混淆,我深表歉意。
头文件:
#ifndef MESSAGE_BUFFER
#define MESSAGE_BUFFER
#define MSG_MAX 4056
typedef struct messageBuffer
{
long recipient; //recipient of message
long senderID; //id number of the sender
char msg[MSG_MAX]; //content of the message
}messageBuffer;
#endif
主线:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/types.h>
#include "message.h"
//function to print usage information upon error
void printUsage(){
printf("Error: Invalid arguments\n");
printf("Usage:\n");
printf("(Create Queue) <-c/C> <key>\n");
printf("(Send a message) <-s/S> <key> <recipient_id> <message>\n");
printf("(Receive a message) <-r/R> <key> <recipient_id>\n"); printf("(Delete queue) <-d/D> <key>\n");
}
//main
int main(int argc, char **argv){
//declare necessary variables
char flag;
int msqid;
messageBuffer mbuf;
size_t buf_length;
int msgflg = IPC_CREAT | 0666;
key_t key;
unsigned long recipient;
//validate arguments
if((argc < 3 || argc > 5) || argv[1][0] != '-' || strlen(argv[1]) != 2){
printf("%d\n", argc);
printUsage();
return -1;
}
flag = argv[1][1];
switch(flag){
//Create a message queue
case 'c':
case 'C':
if((key = atoi(argv[2])) < 1){
printf("Error assigning key");
return -1;
}
if((msqid = msgget(key, msgflg)) < 1){
printf("Error creating queue:");
return -1;
}
printf("%s%i\n", "Key: ", key);
printf("%s%i\n", "msqid: ", msqid);
break;
//Send a message
case 's':
case 'S':
if((key = atoi(argv[2])) < 1){
perror("Error assigning key:");
return -1;
}
if((msqid = msgget(key, 0400)) < 1){
perror("Error accessing queue:");
}
mbuf.recipient = atoi(argv[3]);
strncpy(mbuf.msg, argv[4], MSG_MAX);
buf_length = strlen(mbuf.msg) + 1;
if(msgsnd(msqid, &mbuf, buf_length, 0) < 0){
perror("Error sending message:");
return -1;
}
printf("Message sent (%lu): %s\n", mbuf.recipient, mbuf.msg);
break;
//Receive a message
case 'r':
case 'R':
if((key = atoi(argv[2])) < 1){
perror("Error assigning key:");
return -1;
}
if((msqid = msgget(key, 0400)) < 1){
perror("Error accessing queue:");
}
recipient = atoi(argv[3]);
if( msgrcv(msqid, &mbuf, MSG_MAX, recipient, 0)< 0){
perror("Error receiving message:");
return -1;
}
printf("Message received (%lu):\n", mbuf.recipient);
printf("%s\n", mbuf.msg);
break;
//Delete a message queue
case 'd':
case 'D':
if((key = atoi(argv[2])) < 1){
perror("Error assigning key");
return -1;
}
if((msqid = msgget(key, 0400)) < 1){
perror("Error accessing queue:");
}
printf("%d\n", msqid);
if((msgctl(msqid, IPC_RMID, NULL)) < 0){
perror("Delete message queue failed:");
}
break;
//invalid flag
default:
printUsage();
return -1;
}
return 0;
}
如有任何意见,我将不胜感激。谢谢。
事实证明问题出在指定正在传递的结构的大小上。我已将代码 "buf_length = strlen(mbuf.msg) + 1;" 更改为 buf_length = (sizeof(mbuf.msg) + 1);