【发布时间】:2020-07-16 06:10:16
【问题描述】:
所以我有两个连接到消息队列的程序,一个以结构的形式向另一个发送消息。但是,当我在收到该结构后尝试访问它时,会出现分段错误。
我不知道在结构发送后我需要做什么才能访问它。
这是我的发件人代码:
#include <stdio.h>
#include <mqueue.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
typedef struct {
char path[2048];
char shm_name[50];
size_t shm_s;
char sem_send_name[50];
char sem_recv_name[50];
} cache_request;
static void showAttr(mqd_t fd)
{
struct mq_attr attr;
mq_getattr(fd, &attr);
printf("maxmsg = %ld\n", attr.mq_maxmsg);
printf("msgsize = %ld\n", attr.mq_msgsize);
printf("curmsgs = %ld\n", attr.mq_curmsgs);
}
int main()
{
mqd_t fd;
int ret;
struct mq_attr attr;
int flags = O_RDWR | O_CREAT;
attr.mq_flags = 0;
attr.mq_maxmsg = 3;
attr.mq_msgsize = 2216;
attr.mq_curmsgs = 0;
fd = mq_open("/mq", flags,(S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH),&attr );
if (fd < 0) {
printf("open failed %d\n", fd);
exit(EXIT_FAILURE);
}
printf("open ok\n");
sleep(1);
showAttr(fd);
cache_request* msg = (cache_request*)malloc(sizeof(cache_request));
strcpy(msg->path,"ok\n");
strcpy(msg->shm_name, "ex1\n");
msg->shm_s = 250;
strcpy(msg->sem_send_name," ex2");
strcpy(msg->sem_recv_name, "ex3");
printf("hmm %s\n", msg->shm_name);
printf("hmm %ld\n", msg->shm_s);
//res = mq_receive(fd, (char*) &msg, sizeof(cache_request), NULL);
int res = mq_send(fd, (const char*) &msg, sizeof(cache_request), 0);
if (res < 0) {
printf (" Error %d (%s) on server mq_send.\n",
errno, strerror (errno));
mq_close(fd);
mq_unlink("/mq");
exit (1);
}
sleep(10);
ret = mq_close(fd);
if (ret != 0) {
printf("open failed\n");
exit(EXIT_FAILURE);
}
printf("close ok\n");
sleep(20);
mq_unlink("/mq");
return 0;
}
这是接收器:
#include <stdio.h>
#include <mqueue.h> // for message queue
#include <sys/stat.h>
#include <stdlib.h> // for EXIT_FAILURE
#include <string.h>
#include <errno.h>
#include <unistd.h>
/*
gcc [file] -lrt
*/
typedef struct {
char path[2048];
char shm_name[50];
size_t shm_s;
char sem_send_name[50];
char sem_recv_name[50];
} cache_request;
static void showAttr(mqd_t fd)
{
struct mq_attr attr;
mq_getattr(fd, &attr);
printf("maxmsg = %ld\n", attr.mq_maxmsg);
printf("msgsize = %ld\n", attr.mq_msgsize);
printf("curmsgs = %ld\n", attr.mq_curmsgs);
}
int main()
{
mqd_t fd;
int ret;
mq_unlink("/mq");
struct mq_attr attr;
int flags = O_RDWR;
attr.mq_flags = 0;
attr.mq_maxmsg = 3; // ***
attr.mq_msgsize = 141;
attr.mq_curmsgs = 0;
while((fd = mq_open("/mq", O_RDWR)) == -1){
printf("Couldnt connect to message queue in cache\n");
sleep(2);
}
if (fd < 0) {
printf("open failed %d\n", fd);
exit(EXIT_FAILURE);
}
printf("open ok\n");
//sleep(5);
showAttr(fd);
char* rsp_msg = (char*)malloc(2216);
int res = mq_receive(fd, (char*) &rsp_msg, 2216, NULL);
printf("recieved: %d\n", res);
printf("should be %ld\n", sizeof(cache_request));
if (res < 0) {
printf (" Error %d (%s) on server mq_receive.\n",
errno, strerror (errno));
mq_close(fd);
mq_unlink("/mq");
exit (1);
}
cache_request* msg = (cache_request*)rsp_msg;
printf("shm_s: %ld\n", msg->shm_s); //THIS is where the seg fault happens
printf("shm_name: %s\n", msg->shm_name);
ret = mq_close(fd);
if (ret != 0) {
printf("close failed\n");
exit(EXIT_FAILURE);
}
printf("close ok\n");
return 0;
}
【问题讨论】:
-
OT:关于:
cache_request* msg = (cache_request*)malloc(sizeof(cache_request));1) 在 C 中,返回的类型是void*,可以分配给任何指针。强制转换只会使代码混乱并且容易出错。 2) 始终检查 (!=NULL) 返回值以确保操作成功。如果不成功,请致电:perror( "malloc failed" ); exit( EXIT_FAILURE ); -
关于:
printf("open failed %d\n", fd);1) 错误消息应该输出到stderr,而不是stdout2) 当错误来自 C 库函数时,还应该输出错误发生的文本原因到stderr。函数:perror()正确处理这两个动作 -
关于:
while((fd = mq_open("/mq", O_RDWR)) == -1){ printf("Couldnt connect to message queue in cache\n"); sleep(2);1) 错误消息发给stderr,而不是stdout。 2)如果它失败了一次,它会继续失败,所以最好调用exit( EXIT_FAILURE );而不是循环 -
关于:
int res = mq_receive(fd, (char*) &rsp_msg, 2216, NULL);这是为rsp_msg传递“地址的地址”。强烈建议去掉rsp_msg参数前导的&;注意:rsp_msg已经是一个指针。 -
关于:
attr.mq_msgsize = 141;和int res = mq_receive(fd, (char*) &rsp_msg, 2216, NULL);最大消息大小仅为 141,但代码试图传递2216消息大小。建议最大消息大小为(至少)2216
标签: c segmentation-fault posix message-queue