如何从管道读取长?

时间:2011-07-05 22:38:29

标签: c++ c linux pipe

这涉及进程间通信中未命名的管道。 我有一个管道,一个进程在其中存储一个值,另一个进程想要读取这个数值的值,无论是int还是long。

这里很好地描述了http://tldp.org/LDP/lpg/node11.html如何在C中创建管道。我的问题是如何从管道中读取long或int。

从上述页面中摘录:

/* Read in a string from the pipe */
int nbytes = read(fd[0], readbuffer, sizeof(readbuffer));
printf("Received string: %s", readbuffer);

好吧,在genrell我不知道如何在C中处理管道(它就像一个文件?)以及我如何从中读取除字符串以外的数据。

7 个答案:

答案 0 :(得分:2)

你无法“真正”从管道中读取long。你从一个管道读取一个字节序列,如果你能定义一些这些字节所代表的长度的协议,那你就读了很长的。

假设管道的两端都使用相同的long存储表示,如果它们是使用相同的编译器针对相同的体系结构进行编译,或者对于使用相同编译器但使用相同的编译器的情况。 ABI,那么你可以write(fd, &src_long, sizeof(long));在一端,read(fd, &dst_long, sizeof(long));在另一端。加上或减去通常的混乱以确保I / O没有提前完成。

答案 1 :(得分:1)

管道就像一个文件,除了它是不可见的。当您读取数据时,它会从管道“消失”,无法再次读取。

您将从任何其他文件中读取数据结构。它可以用scanf,fstream>>完成。或者使用read()和union。

答案 2 :(得分:1)

由于管道的两端都在同一台机器上,因此您不必担心机器架构的差异;如果你改变了讨论套接字的问题,你将不得不担心。

您可以使用以下方法将长句写入管道

long l = 0x01020304L
if (write(pipe_w_fd, &l, sizeof(l)) != sizeof(l))
    ...handle error...

您可以使用以下方法读取管道中的值:

long l;
if (read(pipe_r_fd, &l, sizeof(l)) != sizeof(l))
    ...handle error...

如果你必须处理不同的机器架构,你可以将值格式化为平台中立格式(例如big-endian)并在一端写入,并在另一端读取平台中立数据,转换回本地机器特定的格式。

答案 3 :(得分:0)

取决于它是如何发送的。如果你有一些协议/框架约定,你将不得不读取框架,然后提取int。如果你只发送int本身,你可以读取sizeof(int)字节,然后直接使用缓冲区中的字节:

int foo = *((int*) readbuffer);

由于管道是本地管道,因此您不必(在大多数情况下)关注字节序和大小。

答案 4 :(得分:0)

  

好吧,在genrell我不知道如何在C中处理管道(它就像一个文件?)

  

以及如何从中读取除字符串以外的数据。

这是一种天真的情况,它假设long是二进制的并且系统中的大小相同。如果long被写成字符串,则读取一个字符串然后找到long。

long mylong;
int nbytes = read(fd[0], &mylong, sizeof(long));

答案 5 :(得分:0)

它被视为文件。我会阅读scanf以查看您可以轻松解析的数据。像整数和十六进制或八进制的整数这样的东西可以很容易地解析,甚至可以解析指针。 Longs不是那么简单,但是您可以从字符串(%s)中解析long并将其存储很久。

http://beej.us/guide/bgc/output/html/multipage/scanf.html

答案 6 :(得分:0)

你可以这样做:

long l;

if (read(fd[0], &l, sizeof(l)) != sizeof(l))
{
   /* TODO: handle this */
}

通过使序列化类型为long,您在此处会失去一些灵活性,因为读取此数据的人可能会以long的不同字节顺序或不同的大小结束。想象一下,例如,你forkdup2(fd[1], 1) t hen最终exec - 子进程中的SSH命令...现在数据可能来自另一台机器,并且会出现问题。为了避免它,你可以这样做:

/* Type of l has a predictable size. */
uint32_t l;

if (read(fd[0], &l, sizeof(l)) != sizeof(l))
{
   /* TODO: handle this */
}

/* Convert byte order of what we just read */
l = ntohl(l);

实际上,read以32位为增量有点奇怪......你应该考虑的是提出一种消息格式并一次读取更大的数据块。实现此目的的一个好方法是,每个数量的信息都有一个标题,指示后面的内容大小,消息类型等。或者,如果您没有发现这个吸引人的内容,您可以考虑将序列化作为文本。这也可以为字节序问题提供一个合适的答案。