如何从管道中读取长数据?
这涉及进程间通信中的未命名管道。 我有一个管道,一个进程在其中存储一个值,另一个进程想要读取这个数值(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);
嗯,总的来说,我不知道在 C 中如何处理管道(它就像一个文件?)以及如何从中读取字符串以外的数据。
This concerns unnamed pipes in interprocess communication.
I have a pipe and one process stores a value in it and the other want to read this valus which is numerical, either int or long.
It is well described here http://tldp.org/LDP/lpg/node11.html how to create pipes in C. My question is how to read a long or int from a pipe.
extract from above mentioned page:
/* Read in a string from the pipe */
int nbytes = read(fd[0], readbuffer, sizeof(readbuffer));
printf("Received string: %s", readbuffer);
well, in generell i have no idea how a pipe is treated in C (It is like a file?) and how i can read data other than a string from it.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
您无法“真正”从管道中读取
long
。您从管道中读取一个字节序列,如果您可以定义这些字节代表的某个协议,那么您就读取了一个 long。假设管道的两端都使用相同的 long 存储表示,如果它们是使用相同架构的相同编译器编译的,或者使用不同编译器但使用相同的编译器,则它们是这样的ABI,那么您可以在一端写入(fd, &src_long, sizeof(long));,然后读取(fd, &dst_long, sizeof(long));代码> 在另一端。加上或减去通常的混乱以确保 I/O 不会提前完成。
You can't "really" read a
long
from a pipe. You read a sequence of bytes from a pipe, and if you can define some protocol for which long those bytes represent, then you've read a long.Assuming that both ends of the pipe are using the same storage representation for
long
, which they are if they were compiled with the same compiler for the same architecture, or for that matter with different compilers but using the same ABI, then you canwrite(fd, &src_long, sizeof(long));
at one end, andread(fd, &dst_long, sizeof(long));
at the other end. Plus or minus the usual messing about to ensure the I/O didn't finish early.管道就像文件一样,只是它是不可查找的。当您读取数据时,它会从管道中“消失”,并且无法再次读取。
您可以像从任何其他文件中一样读取数据结构。可以用scanf、fstream>>来完成或者使用 read() 和 union。
A pipe is just like a file, except it is unseekable. When you read data, it is "gone" from the pipe and can't be read again.
You would read a datastructure like you would from any other file. It can be done with scanf, fstream>> or with a read() and a union.
由于管道的两端都在同一台机器上,因此您不必担心机器架构的差异;如果你改变问题来讨论套接字,你就不得不担心这个问题。
您可以使用以下方法向管道写入一个长整型值:
您可以使用以下方法从管道中读取值:
如果您必须处理不同的机器体系结构,则可以将值格式化为与平台无关的格式(例如大端)并在一端写入该数据,在另一端读取与平台无关的数据并转换回本地机器特定的格式。
Since both ends of your pipe are on the same machine, you don't have to worry about differences in machine architectures; if you changed the question to discuss sockets, you would have to worry about that.
You can write a long to the pipe using:
And you can read the value off the pipe using:
If you had to deal with different machine architectures, you'd format the value into a platform-neutral format (e.g. big-endian) and write that on one end, and read the platform-neutral data on the other end and convert back to the local machine-specific format.
取决于如何发送。如果您有一些协议/帧约定,则必须读取帧然后提取 int。如果您只发送 int 本身,则可以读取 sizeof(int) 字节,然后直接使用缓冲区中的字节:
由于管道是本地的,因此您不必(在大多数情况下)关心字节序和大小这里。
Depends on how it's sent. If you have some protocol / framing convention, you'll have to read the frame and then extract the int. If you're sending just the int itself, you can read sizeof(int) bytes and then use the bytes in the buffer directly:
Since the pipe is local, you won't have to (in most cases) care about endianness and sizes here.
是的。
这是简单的情况,假设 long 是二进制的并且在系统中具有相同的大小。如果 long 被写为字符串,则读取字符串然后找到 long。
Yes.
This is the naive case, which assumes the long is binary and the same size in the system. If the long was written as a string, read a string then find the long.
它被视为一个文件。我会阅读 scanf 来看看您可以轻松解析哪些数据。像整数、十六进制或八进制整数这样的东西可以很容易地解析,甚至指针也可以解析。 Long 并不那么简单,但您可以从字符串 (%s) 中解析出 long,然后将其存储在 long 中。
http://beej.us/guide/bgc/output/html/multipage /scanf.html
It is treated like a file. I would read up on scanf to see what data you can easily parse. Things like integers, and integers in hex or oct can be easily parsed, even pointers can be parsed. Longs are not as simple, but you can just parse a long from a string (%s) and store it in a long later.
http://beej.us/guide/bgc/output/html/multipage/scanf.html
您可以这样做:
通过将序列化类型设置为
long
,您会失去一些灵活性,因为读取此数据的任何人都可能会得到不同的字节顺序或不同的大小长
。举个例子,假设您fork
和dup2(fd[1], 1)
t最终在子进程中执行 SSH 命令...现在数据可能来自另一台机器,并且会出现问题。为了避免这种情况,你可以这样做:
实际上,以 32 位增量读取有点奇怪......你应该考虑的是提出一种消息格式并读取更大的消息块一次数据。实现此目的的一个好方法是为每个信息量提供一个标头,指示后续内容的大小、消息类型等。或者,如果您觉得这不吸引人,您可以考虑将序列化为文本。这也将为字节顺序问题提供一个不错的答案。
You can do this:
By having your serialization type be
long
you lose some flexibility here, as it may be possible that whoever is reading this data ends up with different byte order or a different size forlong
. Imagine, as an example, that youfork
anddup2(fd[1], 1)
then end up
exec
-ing an SSH command in the child process... Now the data potentially comes from another machine, and there will be problems. To avoid it you can do something like this:In actuality it's a little strange to
read
in 32-bit increments... What you should consider is to come up with a message format and read larger chunks of data at a time. A good way to accomplish this is for each quantity of information to have a header that indicates the size of what follows, message type, etc. Or if you don't find this appealing you can consider having your serialization be text. This would also provide a decent answer to the endianness problem.