读取/写入结构以在C中访问fifo [英] Read/Write struct to fifo in C

查看:58
本文介绍了读取/写入结构以在C中访问fifo的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用命名管道在进程之间传递结构.我在尝试打开管道非阻塞模式时陷入困境.这是我写给fifo的代码:

I'm trying to pass structs between processes using named pipes. I got stuck at trying to open the pipe non-blocking mode. Here's my code for writing to the 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的指针,它已分配,因此不存在带有fifo或smth这样名称的问题.如果我打开不带O_NONBLOCK选项的fifo,则它会第一次写入smth,但随后会阻塞,因为我也难以读取该结构.并在第一次创建初始fifo之后,出现了其他fifo,名为.","..".设置O_NONBLOCK选项后,它将创建fifo,但始终会引发错误:无此设备或地址".知道为什么会这样吗?谢谢.

routing_table is a pointer to my struct, it's allocated, so there's no prob with the name of the fifo or smth like that. If I open the fifo without the O_NONBLOCK option, it writes smth for the first time, but then it blocks because I'm having troubles reading the struct too. And after the first time, the initial fifo is created, but other fifo's appear, named '.', '..'. With O_NONBLOCK option set, it creates the fifo but always throws an error: 'No such device or address'. Any idea why this happens? Thanks.

好的,所以我现在很清楚关于打开fifo的信息,但是我还有另一个问题,实际上,我要从读取/写入fifo的结构开始.我的代码读取该结构:

Ok, so I'm clear now about opening the fifo, but I have another problem, in fact reading/writing the struct to the fifo was my issue to start with. My code to read the struct:

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始终< = 0.我环顾四周,仅发现此示例具有简单的读/写操作,编写结构时还需要更多吗?

It opens the fifo and tries to read, but it seems like nothing is in the fifo, although in writeUpdate the first time it says it wrote 4 bytes (this seems wrong too). At reading, first time around it prints 'a' and then num_bytes is always <=0. I've looked around and only found this example, with simple write/read, is there smth more needed when writing a struct?

我的结构如下:

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 手册页,您将看到在以下情况下尤其会报告此错误:

"No such device or address" is the ENXIO error message. If you look at the open man page, you'll see that this error is reported in particular if:

O_NONBLOCK |设置了O_WRONLY,命名文件是FIFO,没有进程已打开文件以供阅读.(...)

O_NONBLOCK | O_WRONLY is set, the named file is a FIFO and no process has the file open for reading. (...)

这正是您的情况.因此,您看到的行为是正常的:您无法向没有读取器的管道写入(无阻塞).如果未将任何内容连接到管道以进行读取,则内核将不会缓冲您的消息.

which is exactly your situation. So the behavior you are seeing is normal: you can't write (without blocking) to a pipe that has no readers. The kernel won't buffer your messages if nothing is connected to the pipe for reading.

因此,请确保在生产者"之前启动消费者",或删除生产者上的非阻塞选项.

So make sure you start the "consumer(s)" before your "producer", or remove the non-blocking option on the producer.

顺便说一句:在大多数情况下,使用 access 可以使自己对检查时间到使用时间问题.不要使用它.尝试 mkfifo -如果有效,那就很好.如果由于 EEXISTS 而失败,那么您也很好.如果失败,请清理并纾困.

BTW: using access is, in most circumstances, opening yourself to time of check to time of use issues. Don't use it. Try the mkfifo - if it works, you're good. If it fails with EEXISTS, you're good too. If it fails otherwise, clean up and bail out.

对于您问题的第二部分,它实际上完全取决于您要发送的数据的结构.用C序列化一个随机结构根本不容易,特别是如果它包含变量数据(例如 char * s).

For the second part of your question, it really depends completely on how exactly the data you are trying to send is structured. Serializing a random struct in C is not easy at all, especially if it contains variable data (like char *s for example).

如果您的结构仅包含基本类型(而没有指针),并且两面都在同一台计算机上(并且使用同一编译器进行编译),则原始的 write 会在一侧,而 read 可以在整个结构中使用.

If you struct contains only primitive types (and no pointers), and both sides are on the same machine (and compiled with the same compiler), then a raw write on one side and read on the other of the whole struct should work.

例如,您可以查看 C-序列化技术,以获取更复杂的数据类型.

You can look at C - Serialization techniques for more complex data types for example.

关于您的特定示例:指向结构的指针和纯结构的指针之间混杂在一起.

Concerning your specific example: you're getting mixed up between pointers to your structs and plain structs.

在写信方面,您有:

int num_bytes = write(fd_write, routing_table, sizeof(routing_table));

这是不正确的,因为 routing_table 是一个指针.您需要:

This is incorrect since routing_table is a pointer. You need:

int num_bytes = write(fd_write, routing_table, sizeof(*routing_table));
// or sizeof(struct rttable)

在阅读方面也是如此.就接收大小而言,据我所知,您也没有分配 updateData .您也需要这样做(使用 malloc ,并记得将其释放).

Same thing on the read side. On the receiving size you're also not allocating updateData as far as I can tell. You need to do that too (with malloc, and remember to free it).

struct rttable *updateData = malloc(sizeof(struct rrtable));

这篇关于读取/写入结构以在C中访问fifo的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆