如何从pipe道读取一个长的?

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

这是很好的描述http://tldp.org/LDP/lpg/node11.html如何在C中创buildpipe道。我的问题是如何从pipe道中读取长或int。

摘自上面提到的页面:

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

那么,在generell我不知道如何在C(这就像一个文件?)处理pipe道,以及如何我可以读取除string以外的数据。

你不能“真的”从一个管道里读long 。 你从一个管道读取一个字节序列,如果你能定义一些长的字节代表的协议,那么你就读了一个长的字节。

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

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

你会像读取其他文件一样读取数据结构。 它可以用scanf,fstream >>或read()和union来完成。

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

您可以使用以下命令对管道进行长写操作:

 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),然后把它写在一端,然后在另一端读取与平台无关的数据,然后转换回本地机器特定的格式。

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

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

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

那么,在generell我不知道如何在C中处理管道(这就像一个文件?)

是。

以及如何我可以读取数据比从它的字符串。

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

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

它被视为一个文件。 我会阅读scanf,看看你可以轻松地解析什么数据。 像整数和十六进制或十进制的整数可以很容易地解析,甚至可以解析指针。 longs不是那么简单,但是你可以从一个字符串(%s)中解析一个long,并在很久以后存储它。

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

你可以这样做:

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

通过让序列化类型变long这里会失去一些灵活性,因为读取这些数据的人可能会以不同的字节顺序或不同的long 。 想象一下,作为一个例子,你forkdup2(fd[1], 1)最终在子进程中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); 

实际上,以32位的增量read有点奇怪…你应该考虑的是提出一个消息格式,并一次读更大的数据块。 一个好的方法是让每一个信息量都有一个标题,表明后面的大小,消息类型等等。或者如果你没有找到这个吸引人的地方,你可以考虑让你的序列化为文本。 这也将提供一个体面的问题的正确答案。