关于 sending/recieving 大量数据(unix-)套接字的另一个困惑
Yet another confustion about sending/recieving large amount of data over (unix-) socket
我有一个 C++ 程序,它从高速摄像机读取帧并将每个帧写入套接字(unix 套接字)。每次写入为 4096 字节。每帧大约 5MB。 (不能保证帧大小是恒定的,但它始终是 4096 字节的倍数。)
有一个 python 脚本,它在每次调用 recv
时从套接字读取 10 * 4096 字节。我经常遇到意想不到的行为,我认为这可以归结为了解以下有关套接字的内容。我相信我的两个程序都write
/recv
处于阻塞模式。
- 我可以一次写完整帧吗(用5MB数据写call)?推荐吗?速度是这里的主要问题。
- 如果python客户端读取失败或读取速度慢于写入速度,是否意味着一段时间后对套接字的写入操作不会添加到缓冲区?或者,他们会覆盖缓冲区吗?如果没有人在读取套接字,我不介意覆盖缓冲区。
理想情况下,我希望我的应用程序尽可能快地写入套接字。如果没有人在读取数据,那么覆盖就可以了。如果有人正在从套接字读取数据但读取速度不够快,我想将所有数据存储在缓冲区中。那我如何在读取速度慢时强制我的套接字增加缓冲区大小?
这听起来像是一个设计缺陷,您需要首先通过套接字发送这么多数据,并且存在 reader 跟不上作者的风险。作为替代方案,您可能需要考虑使用增量编码,您可以在 "key frame"s(整帧)和编码为前一帧增量的多个帧之间交替。您可能还想考虑将数据写入本地缓冲区,然后在您的 UNIX 域套接字上实现自定义协议,该协议允许读取从给定时间戳开始的一系列帧或给定时间戳的单个帧。如果所有读取都通过此类缓冲区而不是直接从源读取,我想您还可以在该协议中添加额外的编码/压缩选项。此外,如果将数据导出到 UNIX 套接字的服务器应用程序与读取数据并将其写入缓冲区的应用程序是一个独立的应用程序,则您无需担心数据摄取被慢 readers.
Can I write whole frame in one go (write call with 5MB of data)? Is it
recommended? Speed is major concern here.
好吧,您当然可以 尝试 ,但是如果对 socket.send() 的调用只发送了一部分字节,请不要太惊讶要求它发送。特别是,您应该始终检查 socket.send() 的 return 值,以查看它 实际上 从您那里接受了多少字节,因为该值可能大于零但小于您传递给调用的字节数。 (如果它更少,那么您可能需要再次调用 socket.send() 以从您的缓冲区中发送第一次调用未处理的剩余字节......并根据需要重复;或者您可以调用 socket.sendall() 而不是 socket.send(),这将为您执行必要的循环和重新调用 socket.send() 命令,因此您不必担心它......权衡是 socket.sendall() 可能不会 return 很长一段时间,这取决于你的网络连接速度和你告诉 socket.send 的数据量all() 发送)
请注意,在发送数据报时,通常会强制执行最大数据包大小;大于该值的数据包要么被分割成更小的数据包进行传输(并希望在接收端重新组装),要么它们可能只是被丢弃。例如,当通过以太网发送 UDP 数据包时,通常有一个 MTU of 1500 bytes. When sending over a Unix socket the MTU will likely be larger than that, but likely there will still be a limit.
If python client fails to read or read slowly than write, does it mean
that after some time write operation on socket would not add to
buffer? Or, would they overwrite the buffer? If no-one is reading the
socket, I'd not mind overwriting the buffer.
如果您在流式套接字 (SOCK_STREAM) 上发送,则慢速客户端会导致服务器的 send() 调用阻塞 if/when 缓冲区已满。如果您在数据报样式套接字 (SOCK_DGRAM) 上发送并且缓冲区已满,则 "overflow" 数据报将被简单地丢弃。
Then how can I force my socket to increase the buffer size when
reading is slow?
您可以通过 设置套接字的发送缓冲区大小。请注意,这通常是提前完成的(例如,在创建套接字之后立即完成)而不是尝试这样做 "on the fly" 以响应缓慢的 reader.
我有一个 C++ 程序,它从高速摄像机读取帧并将每个帧写入套接字(unix 套接字)。每次写入为 4096 字节。每帧大约 5MB。 (不能保证帧大小是恒定的,但它始终是 4096 字节的倍数。)
有一个 python 脚本,它在每次调用 recv
时从套接字读取 10 * 4096 字节。我经常遇到意想不到的行为,我认为这可以归结为了解以下有关套接字的内容。我相信我的两个程序都write
/recv
处于阻塞模式。
- 我可以一次写完整帧吗(用5MB数据写call)?推荐吗?速度是这里的主要问题。
- 如果python客户端读取失败或读取速度慢于写入速度,是否意味着一段时间后对套接字的写入操作不会添加到缓冲区?或者,他们会覆盖缓冲区吗?如果没有人在读取套接字,我不介意覆盖缓冲区。
理想情况下,我希望我的应用程序尽可能快地写入套接字。如果没有人在读取数据,那么覆盖就可以了。如果有人正在从套接字读取数据但读取速度不够快,我想将所有数据存储在缓冲区中。那我如何在读取速度慢时强制我的套接字增加缓冲区大小?
这听起来像是一个设计缺陷,您需要首先通过套接字发送这么多数据,并且存在 reader 跟不上作者的风险。作为替代方案,您可能需要考虑使用增量编码,您可以在 "key frame"s(整帧)和编码为前一帧增量的多个帧之间交替。您可能还想考虑将数据写入本地缓冲区,然后在您的 UNIX 域套接字上实现自定义协议,该协议允许读取从给定时间戳开始的一系列帧或给定时间戳的单个帧。如果所有读取都通过此类缓冲区而不是直接从源读取,我想您还可以在该协议中添加额外的编码/压缩选项。此外,如果将数据导出到 UNIX 套接字的服务器应用程序与读取数据并将其写入缓冲区的应用程序是一个独立的应用程序,则您无需担心数据摄取被慢 readers.
Can I write whole frame in one go (write call with 5MB of data)? Is it recommended? Speed is major concern here.
好吧,您当然可以 尝试 ,但是如果对 socket.send() 的调用只发送了一部分字节,请不要太惊讶要求它发送。特别是,您应该始终检查 socket.send() 的 return 值,以查看它 实际上 从您那里接受了多少字节,因为该值可能大于零但小于您传递给调用的字节数。 (如果它更少,那么您可能需要再次调用 socket.send() 以从您的缓冲区中发送第一次调用未处理的剩余字节......并根据需要重复;或者您可以调用 socket.sendall() 而不是 socket.send(),这将为您执行必要的循环和重新调用 socket.send() 命令,因此您不必担心它......权衡是 socket.sendall() 可能不会 return 很长一段时间,这取决于你的网络连接速度和你告诉 socket.send 的数据量all() 发送)
请注意,在发送数据报时,通常会强制执行最大数据包大小;大于该值的数据包要么被分割成更小的数据包进行传输(并希望在接收端重新组装),要么它们可能只是被丢弃。例如,当通过以太网发送 UDP 数据包时,通常有一个 MTU of 1500 bytes. When sending over a Unix socket the MTU will likely be larger than that, but likely there will still be a limit.
If python client fails to read or read slowly than write, does it mean that after some time write operation on socket would not add to buffer? Or, would they overwrite the buffer? If no-one is reading the socket, I'd not mind overwriting the buffer.
如果您在流式套接字 (SOCK_STREAM) 上发送,则慢速客户端会导致服务器的 send() 调用阻塞 if/when 缓冲区已满。如果您在数据报样式套接字 (SOCK_DGRAM) 上发送并且缓冲区已满,则 "overflow" 数据报将被简单地丢弃。
Then how can I force my socket to increase the buffer size when reading is slow?
您可以通过