Python 关于通过(unix-)套接字发送/接收大量数据的另一个困惑 我有一个C++程序,它从高速摄像机读取帧,并将每个帧写入一个套接字(UNIX套接字)。每次写入为4096字节。每个帧大约为5MB。(无法保证帧大小是恒定的,但它始终是4096字节的倍数。)

Python 关于通过(unix-)套接字发送/接收大量数据的另一个困惑 我有一个C++程序,它从高速摄像机读取帧,并将每个帧写入一个套接字(UNIX套接字)。每次写入为4096字节。每个帧大约为5MB。(无法保证帧大小是恒定的,但它始终是4096字节的倍数。),python,c++,sockets,unix-socket,Python,C++,Sockets,Unix Socket,有一个python脚本可以从套接字读取:每次调用recv时读取10*4096字节。我经常会遇到意想不到的行为,我认为这可以归结为理解以下关于套接字的内容。我相信我的两个程序都是在阻塞模式下编写的 我可以一次写入整个帧吗(使用5MB数据写入调用)?推荐吗?速度是这里的主要问题 若python客户端读失败或读慢于写,是否意味着在一段时间后套接字上的写操作将不会添加到缓冲区?或者,他们会覆盖缓冲区吗?如果没有人读取套接字,我不介意覆盖缓冲区 理想情况下,我希望我的应用程序尽可能快地写入套接字。如果

有一个python脚本可以从套接字读取:每次调用
recv
时读取10*4096字节。我经常会遇到意想不到的行为,我认为这可以归结为理解以下关于套接字的内容。我相信我的两个程序都是在阻塞模式下编写的

  • 我可以一次写入整个帧吗(使用5MB数据写入调用)?推荐吗?速度是这里的主要问题
  • 若python客户端读失败或读慢于写,是否意味着在一段时间后套接字上的写操作将不会添加到缓冲区?或者,他们会覆盖缓冲区吗?如果没有人读取套接字,我不介意覆盖缓冲区

理想情况下,我希望我的应用程序尽可能快地写入套接字。如果没有人读取数据,则可以进行覆盖。如果有人正在从套接字读取数据,但读取速度不够快,我希望将所有数据存储在缓冲区中。那么,当读取速度较慢时,如何强制套接字增加缓冲区大小呢?

这听起来像是一个设计缺陷,您需要首先通过套接字发送这么多数据,并且存在读卡器跟不上写入器的风险。作为另一种选择,您可能需要考虑使用增量编码,其中在“关键帧”S(整个帧)和从先前帧中编码为多个Delta的多个帧之间交替。您还可以考虑将数据写入本地缓冲区,然后在UNIX域套接字上实现自定义协议,该协议允许读取给定时间戳或给定时间戳的单个帧的帧序列。如果所有读取都通过这样的缓冲区,而不是直接从源代码读取,我想您还可以在该协议中添加额外的编码/压缩选项。此外,如果将数据导出到UNIX套接字的服务器应用程序是与读取数据并将其写入缓冲区的应用程序不同的应用程序,您不必担心数据摄取会被速度较慢的读卡器阻塞。

这听起来像是一个设计缺陷,您首先需要通过套接字发送这么多数据,并且存在读卡器跟不上编写器的风险。作为另一种选择,您可能需要考虑使用增量编码,其中在“关键帧”S(整个帧)和从先前帧中编码为多个Delta的多个帧之间交替。您还可以考虑将数据写入本地缓冲区,然后在UNIX域套接字上实现自定义协议,该协议允许读取给定时间戳或给定时间戳的单个帧的帧序列。如果所有读取都通过这样的缓冲区,而不是直接从源代码读取,我想您还可以在该协议中添加额外的编码/压缩选项。此外,如果将数据导出到UNIX套接字的服务器应用程序与读取数据并将其写入缓冲区的服务器应用程序是一个独立的应用程序,那么您就不必担心数据摄取会被速度较慢的读取器阻塞

我可以一次写入整个帧吗(使用5MB数据写入调用)?它是 推荐?速度是这里的主要问题

当然,您可以尝试,但是如果对socket.send()的调用只发送您要求它发送的字节的一部分,请不要太惊讶。特别是,您应该始终检查socket.send()的返回值,以查看它实际从您那里接受了多少字节,因为该值可能大于零,但小于传递给调用的字节数。(如果较小,则可能需要再次调用socket.send(),以从缓冲区中发送第一次调用未处理的剩余字节…并根据需要重复;或者,您可以调用socket.sendall()而不是socket.send(),这将执行必要的循环并重新调用socket.send()命令,这样您就不必担心了……折衷的办法是,socket.sendall()可能在很长一段时间内不会返回,这取决于网络连接的速度以及您告诉socket.sendall()发送的数据量)

请注意,在发送数据报时,通常会强制执行最大数据包大小;大于该值的数据包将被分割成更小的数据包进行传输(并有望在接收端重新组装),或者可能被丢弃。例如,当通过以太网发送UDP数据包时,通常会有1500字节的长度。当通过Unix套接字发送时,MTU可能会大于此值,但很可能会大于此值

如果python客户端无法读取或读取速度慢于写入速度,这是否意味着 一段时间后,套接字上的写入操作将不会添加到 缓冲器或者,他们会覆盖缓冲区吗?如果没有人在阅读 套接字,我不介意覆盖缓冲区

如果您是在流式套接字(SOCK_stream)上发送,那么如果/当缓冲区填满时,较慢的客户端将导致服务器的send()调用被阻塞。如果您使用数据报样式的套接字(SOCK_DGRAM)发送数据,并且缓冲区已满,“溢出”数据报将被丢弃

那么,我如何强制套接字增加缓冲区大小 阅读慢

您可以通过设置套接字的发送缓冲区大小。请注意,这通常是提前完成的(例如,在创建套接字之后),而不是为了响应速度较慢的读取器而尝试“动态”完成

我可以一次写入整个帧吗(使用5MB数据写入调用)?它是 推荐?速度是这里的主要问题

好吧,你当然可以试试,但如果不行,不要太惊讶