从 Linux 上的消息队列读取时出现“错误地址”错误
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10666789/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Error "Bad address" when reading from message queue on Linux
提问by jcubic
I have assignment when I need to write simple time server and a client using Linux message queue. The server opens a message queue and the client sends a request with his PID (message with type 1) and the server reads that message and sends a message with type of PID (taken from the message read). I put all the code below because I don't know where I made the mistake. I'm not Linux programming expert. Don't even know if I written server correct.
当我需要使用 Linux 消息队列编写简单的时间服务器和客户端时,我有任务。服务器打开一个消息队列,客户端发送一个带有他的 PID(类型为 1 的消息)的请求,服务器读取该消息并发送一个带有 PID 类型的消息(取自读取的消息)。我把所有的代码都放在下面,因为我不知道我在哪里犯了错误。我不是 Linux 编程专家。甚至不知道我写的服务器是否正确。
File that is included by server and client (I need to write it in this way).
服务器和客户端包含的文件(我需要以这种方式编写)。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/msg.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include <string.h>
#include <signal.h>
#define QUEUE 100
#define PERM_ALL 0777
typedef struct my_msgbuf {
long mtype;
int pid;
} ClientMessage;
typedef struct my_msgbuf2 {
long mtype;
struct tm time;
} TimeMessage;
Server
服务器
int m_queue;
void cleanup(int signum) {
if (msgctl(m_queue, IPC_RMID, NULL) == -1) {
printf("Something happen on clean up\n");
exit(1);
}
exit(signum);
}
int main() {
ClientMessage pid_message;
TimeMessage t;
time_t clock;
struct tm *cur_time;
if ((m_queue = msgget(QUEUE, PERM_ALL | IPC_CREAT)) == -1) {
printf("Can't create and open message queue\n");
exit(1);
}
printf("created message queue = %d\n", m_queue);
fflush(stdout);
//t = malloc(sizeof(TimeMessage));
signal(SIGINT, cleanup);
while (1) {
if (msgrcv(m_queue, &pid_message, sizeof(pid_message.pid), 1, 0) == -1) {
break;
} else {
t.mtype = pid_message.pid;
clock = time(NULL);
cur_time = localtime(&clock);
memcpy(&t.time, cur_time, sizeof(struct tm));
msgsnd(m_queue, &t, sizeof(struct tm), 0);
}
}
cleanup(0);
}
Client
客户
int main() {
int m_queue;
TimeMessage *t;
ClientMessage client;
if ((m_queue = msgget(QUEUE, PERM_ALL)) == -1) {
perror("Error in opening queue");
exit(1);
}
client.mtype = 1;
client.pid = getpid();
while (1) {
if (msgsnd(m_queue, &client, sizeof(client.pid), 0) == -1) {
perror("Error sending to queue");
exit(1);
} else {
if (msgrcv(m_queue, t, sizeof(struct tm), client.pid, 0) == -1) {
perror("Error reading from queue");
exit(1);
}
printf("time: %d:%d:%d\n", t->time.tm_hour, t->time.tm_min, t->time.tm_sec);
}
}
return 0;
}
Both program compile without errors but client return "Error reading from queue" msgrcv is returning -1.
两个程序都编译没有错误,但客户端返回“从队列读取错误”msgrcv 返回 -1。
采纳答案by another.anon.coward
After adding the perror
it appears that you have got the error stating "Bad Address"
(EFAULT) which means that "The address pointed to by msgp(buffer) isn't accessible". From the code it appears that there has been no memory allocated to TimeMessage *t
so you can either allocate memory or just change it to TimeMessage t
and pass &t
instead of t
to msgrcv
. Also size should be sizeof t
(assuming the change from *t
to t
, or sizeof(TimeMessage)
for *t
) instead of sizeof(struct tm)
(& obviously you would change printf
statement accordingly)
Hope this helps!
添加后perror
,您似乎收到了错误说明"Bad Address"
(EFAULT),这意味着“无法访问msgp(缓冲区)指向的地址”。从代码看来,没有分配内存,TimeMessage *t
因此您可以分配内存或只是将其更改为TimeMessage t
并传递&t
而不是t
to msgrcv
。大小也应该是sizeof t
(假设从*t
tot
或sizeof(TimeMessage)
for更改*t
)而不是sizeof(struct tm)
(显然你会相应地更改printf
语句)
希望这会有所帮助!