在 Python 的 SOCKS 读取循环中处理 EOF
在 SOCKS 精确读取循环中显式处理 EOF,而不是把已关闭的连接当成永远不会到来的超时。
某个循环想要 SOCKS 回复的八个字节。它已经收到三个。下一次读取返回 b'',循环将其追加、检查长度,然后永远重试。
这是 EOF 处理缺陷,不是需要更长超时的慢代理。在普通的流式套接字接收中,空字节串意味着对端已断开。剩下的五个字节不会在这个连接上到达。
精确读取辅助函数需要三种不同的结果:累积非空块、在达到所需长度之前因 EOF 而失败,以及传播超时或其他套接字错误。这些情况不应坍缩成一个通用的重试循环。
在操作之前设置套接字的预期超时,并读取代理协议规定的字段长度。单次接收只能返回回复的一部分。反过来,请求一个很大的固定缓冲区并不会让每个 SOCKS 地址都具有该长度。
不要通过把旧的 MSG_WAITALL 代码片段粘贴进依赖的源码并假设它能处理 EOF、信号和平台行为来修复依赖。优先采用受维护实现所支持的修复;当解析器是你自己的代码时,则刻意实现该辅助函数的契约。
保留期望和实际收到的字节数,但不要记录凭据负载。“八个回复字节中收到三个后遇到 EOF”比“代理又卡住了”能更好地解释这次损坏的交换。