我正在尝试使用命名管道在进程之间传递结构。我在尝试打开管道非阻塞模式时陷入困境。这是我写给fifo的代码:
void writeUpdate() {
// Create fifo for writing updates:
strcpy(fifo_write, routing_table->routerName);
// Check if fifo exists:
if(access(fifo_write, F_OK) == -1 )
fd_write = mkfifo(fifo_write, 0777);
else if(access(fifo_write, F_OK) == 0) {
printf("writeUpdate: FIFO %s already exists\n", fifo_write);
//fd_write = open(fifo_write, O_WRONLY|O_NONBLOCK);
}
fd_write = open(fifo_write, O_WRONLY|O_NONBLOCK);
if(fd_write < 0)
perror("Create fifo error");
else {
int num_bytes = write(fd_write, routing_table, sizeof(routing_table));
if(num_bytes == 0)
printf("Nothing was written to FIFO %s\n", fifo_write);
printf("Wrote %d bytes. Sizeof struct: %d\n", num_bytes,sizeof(routing_table)+1);
}
close(fd_write);
}
routing_table是指向我的struct的指针,它已分配,因此没有profi之类的profo之类的名称。
如果我打开没有O_NONBLOCK选项的fifo,它会第一次写入smth,但随后会阻塞,因为我也难以读取该结构。并在第一次创建初始fifo之后,其他fifo出现,名为“。”,“ ..”。
设置O_NONBLOCK选项后,它将创建fifo,但始终会引发错误:“无此设备或地址”。知道为什么会这样吗?谢谢。
编辑:好的,所以我现在很清楚有关打开fifo的信息,但是我还有另一个问题,实际上,我要从读取/写入fifo的结构开始。我的代码读取该结构:
void readUpdate() {
struct rttable *updateData;
allocate();
strcpy(fifo_read, routing_table->table[0].router);
// Check if fifo exists:
if(access(fifo_read, F_OK) == -1 )
fd_read = mkfifo(fifo_read, 777);
else if(access(fifo_read, F_OK) == 0) {
printf("ReadUpdate: FIFO %s already exists\n Reading from %s\n", fifo_read, fifo_read);
}
fd_read = open(fifo_read, O_RDONLY|O_NONBLOCK);
int num_bytes = read(fd_read, updateData, sizeof(updateData));
close(fd_read);
if(num_bytes > 0) {
if(updateData == NULL)
printf("Read data is null: yes");
else
printf("Read from fifo: %s %d\n", updateData->routerName, num_bytes);
int result = unlink(fifo_read);
if(result < 0)
perror("Unlink fifo error\n");
else {
printf("Unlinking successful for fifo %s\n", fifo_read);
printf("Updating table..\n");
//update(updateData);
print_table_update(updateData);
}
} else
printf("Nothing was read from FIFO %s\n", fifo_read);
}
它打开fifo并尝试读取,但fifo中似乎没有任何内容,尽管在writeUpdate中它第一次说它写入了4个字节(这似乎也是错误的)。读取时,第一次在它周围打印“ a”,然后num_bytes总是 我环顾四周,仅发现此示例具有简单的读/写操作,编写结构时还需要更多吗?
我的结构看起来像这样:
typedef struct distance_table {
char dest[20]; //destination network
char router[20]; // via router..
int distance;
} distance_table;
typedef struct rttable {
char routerName[10];
char networkName[20];
struct distance_table table[50];
int nrRouters;
} rttable;
struct rttable *routing_table;
最佳答案
ENXIO
错误消息是“没有这样的设备或地址”。如果查看open
手册页,则会发现特别是在以下情况下报告此错误:
O_NONBLOCK |设置为O_WRONLY,命名文件为FIFO,没有进程
已打开文件以供阅读。 (...)
这正是您的情况。因此,您看到的行为是正常的:您无法向没有读取器的管道写入(无阻塞)。如果未将任何内容连接到管道以进行读取,则内核将不会缓冲您的消息。
因此,请确保在“生产者”之前启动“消费者”,或删除生产者上的非阻塞选项。
顺便说一句:在大多数情况下,使用access
是使自己适应time of check to time of use问题的能力。不要使用它。尝试mkfifo
-如果有效,那就很好。如果使用EEXISTS
失败,那么您也很好。如果失败,则进行清理并纾困。
对于您问题的第二部分,它实际上完全取决于您尝试发送的数据的结构。用C序列化一个随机结构根本不容易,特别是如果它包含变量数据(例如char *
)。
如果您的结构仅包含基本类型(而没有指针),并且两面都在同一台计算机上(并且使用同一编译器进行编译),则整个结构的一面是原始的write
,另一面是read
应该管用。
例如,您可以查看C - Serialization techniques以获取更复杂的数据类型。
关于您的特定示例:指向结构的指针和纯结构的指针之间混杂在一起。
在写方面,您有:
int num_bytes = write(fd_write, routing_table, sizeof(routing_table));
这是不正确的,因为
routing_table
是指针。你需要:int num_bytes = write(fd_write, routing_table, sizeof(*routing_table));
// or sizeof(struct rttable)
阅读方面也是如此。就接收大小而言,据我所知,您也没有分配
updateData
。您也需要这样做(使用malloc
,并记住要释放它)。struct rttable *updateData = malloc(sizeof(struct rrtable));
关于c - 读取/写入结构以在C中访问fifo,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6080645/