unistd.h read()正在读取更多数据然后被写入

时间:2009-05-16 20:21:13

标签: c++ unix named-pipes memset unistd.h

我正在从命名管道读取/写入数据。在写作方面,它表示它正在写一个恒定的110字节。在阅读方面,大多数时候它表示它正在读取110个字节,这是正确的,但有时它说它读取220字节或330字节。这是正确的,当我打印出来时,它在同一个read()中连续两次或三次打印出相同的消息。在下面的代码中读取我在memset上做错了什么来清除char?除非在缓冲区遗留一些东西,否则我无法想到它正在阅读的任何其他方式。

int fd1, numread;
char bufpipe[5000];

    while(1)
    {
        fd1 = open("/tmp/testPipe", O_RDONLY);
        numread = read(fd1,bufpipe, 5000);//->this should always be 110
        if(numread > 1)
        {
            printf("READ: %i", numread); 
            bufpipe[numread+1] = '\0';
            memset(bufpipe,'\0',5001);
            close(fd1);
        }
    }

3 个答案:

答案 0 :(得分:6)

此:

memset(bufpipe,'\0',5001);

被一个字节覆盖,因为你只有5000个字节。

但主要的“问题”是read(..., 5000)将始终读取尽可能多达5000字节的内容 - 您似乎假设它的读取次数与编写器一次写入的次数相同,这不是真的。如果编写器在两次读取之间写入两个110字节的数据包,则读取器读取220字节是完全正确的。

如果您一次只需要读取一个数据包,则必须使数据包自我描述。因此,例如,前四个字节包含要遵循的字节数。然后,您可以通过读取四个字节来读取单个数据包,将其转换为整数,然后读取该数量的数据字节。

答案 1 :(得分:1)

您假设read将在write之后立即执行。在遇到读取之前,编写器进程可能会多次写入管道。写入的数据将添加到缓冲区的末尾。换句话说,读取和写入不是面向分组的。它们是面向流的。这意味着write只是将数据添加到缓冲区,而read只是为它提供了任何可用的内容。

答案 2 :(得分:0)

你是如何与作家同步的? 您只需阅读您的期望(指定110阅读())