2 回答
TA贡献1877条经验 获得超1个赞
看起来您正在重复使用相同的连接,而发生的情况是您的file_socket
缓冲意味着...您实际上已经recv
从套接字中读取了更多内容,然后您会通过读取循环来思考。
即接收器从您的套接字消耗更多数据,并且下次您尝试readline()
最终读取前一个文件的其余部分,直到其中包含的新行或下一个长度信息。
这也意味着您最初的问题实际上是您跳过了一段时间。下一个读取行的效果不是int
您预期的,因此观察到了失败。
你可以说:
with sock.makefile('rb', buffering=0) as file_socket:
相反,强制文件访问不被缓冲。或者实际自行处理传入字节的接收、缓冲和解析(了解一个文件的结束位置和下一个文件的开始位置)(而不是像包装器和 那样的文件)readline
。
TA贡献2041条经验 获得超4个赞
您必须了解套接字通信是基于 TCP/IP 的,无论是同一台机器(在这种情况下使用环回)还是不同的机器都无关紧要。因此,您已经获得了一些在其之间建立连接的 IP 地址。更进一步,它涉及访问您的网络适配器,即与访问例如网络适配器相比需要相对较长的时间。内存。此外,适配器本身管理何时发送特定数据帧(较低的 ISO/OSI 层)。基本上,对于 TCP,需要 ACK,但在标准 PC 上,这通常不是某些工业实时以太网。
因此,在您的代码中,您有一个while True
没有任何睡眠的循环,并且您不检查sock.send
返回的内容。即使特定数据帧出现问题,您也会忽略它并尝试发送下一个。乍一看,似乎有些内容已被缓存,并且接收者收到了重新建立连接后刷新的内容。
因此,您应该做的第一件事是检查是否sock.send
确实返回了发送的字节数。如果没有,我相信应该重新发送该帧。在这种情况下,我强烈建议的另一件事是考虑一些自定义协议(这通常在 OSI/ISO 堆栈的上下文中称为应用程序层)。例如,您可能有 4 种类型的帧:START、FILESIZE、DATA、END,分配唯一 ID 并以标识符开始每个帧。然后,START 将是空的,FILESIZE 将包含单个 uint16,DATA 将包含 {FILE NUMBER, LINE NUMBER, LINE_LENGTH, LINE},END 将是空的。然后,一旦您在客户端上获得了整个框架,您就可以安全地组合收到的信息。
添加回答
举报