1

我正在从管道中读取。

char buf[255];

while((nbytes = read(fd,buf,sizeof(buf)) > 0)) // fd is the opened pipe
        {

          if(strcmp(buf,"IN")==0){
            printf("%s\n", "SET IN");
          }
          if(strcmp(buf,"OUT")==0){
            printf("%s\n", "SET OUT");
          }
}

现在当我通过终端写入管道时

echo "OUT" > /path/to/FIFO

我得到的输出是:“SET IN”

我输入的所有内容总是以“SET IN”作为输出。如何比较我从管道中读取的字符串?

4

2 回答 2

1

正如 unwind 指出的那样,您不能将管道中的数据直接视为字符串数据并期望一切顺利。

你真正需要做的是为你的数据传输定义一个协议,并编写一些可以发送和接收该协议的东西。

不过,它不必很复杂。

例如,您可能会做一些事情,其中​​前 4 个字节表示您正在发送的数据的长度,然后是数据。当您读取 4 个字节 + 前 4 个字节的数据值时,您将对该数据与一组已知的预期值进行比较。如果您想使用字符串比较函数,部分数据可能包含空终止符。您也可以选择使用 memcmp() 来执行测试,而无需空终止。

发送数据的方式有很多种,虽然这可能感觉有点矫枉过正,但你必须小心,不要假设当你调用一次 read 时,你总会得到你期望的所有数据。在上面的例子中,你会一直调用它直到你得到预期的数据量,可能会缓冲它直到你拥有一切,然后检查它是什么。

于 2013-05-10T07:03:16.830 回答
1

您将读取的数据视为字符串(通过将其传递给strcmp()),但不能保证输入数据以 0 结尾。特别是,read()不会 0 终止数据,如果可能,它将用数据填充整个缓冲区。

您需要自己做,通过将 read 调用修改为:

while((nbytes = read(fd, buf, sizeof buf - 1)) > 0 ) // fd is the opened pipe
{
  buf[nbytes - 1] = '\0';

请注意,传递给的大小read()已缩小以为终止符腾出空间,我们添加了它。

另请注意while,如上面@AhmedMasud 的评论中所述,我更正了 中的括号。这是一个很好的观点,我忘了强调它。

更新:正如xaxxon 的回答所提到的,数据将以不可预测的块传递,因此协议可能很有用。流经管道的文本数据最简单的协议是(当然?)基于行的。这意味着您应该收集数据,直到检测到行尾字符。当你这样做时,解析缓冲区的内容,然后清除它。

于 2013-05-10T06:39:13.257 回答