这涉及进程间通信中未命名的管道。 我有一个管道,一个进程在其中存储一个值,另一个进程想要读取这个数值的值,无论是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中处理管道(它就像一个文件?)以及我如何从中读取除字符串以外的数据。
答案 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并将其存储很久。
答案 6 :(得分:0)
你可以这样做:
long l;
if (read(fd[0], &l, sizeof(l)) != sizeof(l))
{
/* TODO: handle this */
}
通过使序列化类型为long
,您在此处会失去一些灵活性,因为读取此数据的人可能会以long
的不同字节顺序或不同的大小结束。想象一下,例如,你fork
和dup2(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位为增量有点奇怪......你应该考虑的是提出一种消息格式并一次读取更大的数据块。实现此目的的一个好方法是,每个数量的信息都有一个标题,指示后面的内容大小,消息类型等。或者,如果您没有发现这个吸引人的内容,您可以考虑将序列化作为文本。这也可以为字节序问题提供一个合适的答案。