NetworkStream.DataAvailable == false 只表示当前没有可立即读取的字节,并不表示 HTTP 响应已经完整。循环停在这里,可能在数据包之间的间隙截断一次完全正常的 SOCKS 下载。

SOCKS 建立 TCP 连接之后,完成规则仍然由 HTTP 分帧提供:

  • 带 Content-Length 的正文在声明的正文字节之后结束。
  • 分块(chunked)响应需要结束块和适用的尾部字段。
  • 以连接定界的响应随连接的关闭而结束。
  • 部分状态码和 HEAD 的响应没有正文。

要确定适用哪条规则,应读取状态行和响应头。只等待连接关闭并不是通用解法,因为一个完整的 HTTP 响应可以让连接保持打开。单个缓冲区的大小同样与响应长度无关。

当所选代理传输受支持时,应使用 HTTP 客户端的分帧实现。在兼容的现代 .NET 运行时上,可以考虑 HttpClient 原生支持 SOCKS。自行实现时,必须在部分响应头和正文字段的读取之间保留解析状态,并区分正常完成、取消、超时和意外 EOF。对于非空读取请求,读到零字节意味着流已结束;这与此刻队列中暂时没有字节不是一回事。

代理会让时间间隙更明显,但它不会把空接收队列变成消息结束标志。

相关文章