代理检查器设置了 SendTimeout = 200,调用了 Connect,然后等待的时间远超预期。这个超时绑定在一个检查器尚未执行到的操作上。

Socket.SendTimeout 控制的是同步发送。它不会给同步连接尝试一个 200 ms 的期限。在 Connect 之前加一段睡眠,只会再多一层延迟。

取消正在等待的那个操作

在提供可取消重载的现代 .NET 目标上,异步探测可以把预算用在建立连接这一步:

using var budget = new CancellationTokenSource(TimeSpan.FromSeconds(2));
using var client = new TcpClient();
await client.ConnectAsync(proxyHost, proxyPort, budget.Token);

这段代码属于一个 async 方法,代理主机和端口由调用方提供;来自代理列表的公开候选就能提供这两个输入。如果检查器要报告失败原因,请把取消与套接字错误分开处理。释放客户端还能避免已完成的探测不断堆积套接字。

较旧的 .NET Framework 代码没有所有现代重载。请使用受支持的异步连接方式,并在放弃尝试时显式关闭套接字。仅仅停止等待,并不能证明底层的操作已经停止。

绿色的结果仍然只是个小结果

TCP 连接成功只证明这个客户端到达了一个正在监听的端点。它还没有协商 SOCKS、没有向 HTTP 代理认证、没有发出 CONNECT,也没有收到期望的网站响应。

给这些后续阶段各自加上有界的处理,或者让一个有意设定的整体期限贯穿它们。否则,修好的连接计时器可能完美工作,而检查器仍在多花一分钟等待代理握手。

相关文章