12

我得到了 10 台新 PC,全部(据说)都安装了新的 Windows 7 Pro,并且没有对它们进行任何其他操作。

我有一个程序,用 Delphi XE2 编码,使用 Indy 10 组件进行网络连接。我将 TIdTcpCleint 的“连接超时”和“读取超时”属性设置为 500 毫秒,将“重新使用套接字”设置为“o/s 依赖””(我还尝试了将其设置为“否”的构建)并保留“使用 Nagle” (无论设置为真(我也尝试过假)。

这就是问题所在:当我在这些 PC 上运行相同的 .EXE 并测试我拉网线的情况时,我的调试跟踪显示连接尝试/连接超时发生在同一秒或下一秒(粒度为 1秒) - 但在其他情况下,我看到连接超时之前是 20 或 21 秒。

尽管我看到没有安装任何应用程序,但似乎有些 PC 并不像声称的那样完全“全新安装”。也许有人安装了某些东西然后将其删除,也许他们试图调整性能。

在我在 10 台 PC 上重新安装 Windows 之前,有人可以建议在哪里查看吗?关于 TCP 客户端连接超时,20(或 21)秒是否会响铃?

[更新] 我正在尝试直接连接到特定的 IP 地址,所以我不确定@Nikolai 检查 DNS 的建议是否相关。很抱歉最初没有提到这一点。

[更新] 程序不会尝试保持套接字打开。它连接、发送一些数据和断开连接——对于每条新数据重复。

4

2 回答 2

7

可悲的是,这正在按预期工作。连接确实已经超时。Indy 确定连接将在您要求的 500 毫秒内失败。但是,这并不能保证函数会返回

连接超时后,Indy 会关闭连接以释放其所有资源。它同步执行此操作。这意味着您最终会等待底层 TCP 操作失败。这通常需要 20 秒。

解决方案是在线程中调用connect。信不信由你,这就是 Indy 已经为实现超时所做的事情。但是,当它等待线程超时时,它会尝试关闭主线程中的连接。您需要将其推迟到工作线程。

至于为什么它在某些系统上立即发生,而在其他系统上则在 20 秒内发生,这取决于精确的网络配置。例如,如果启用了 IPv6,堆栈可能会尝试使用 IPv6 到 IPv4 的连接,即使物理接口关闭,也可能不会报告关闭。无法保证立即检测到无法连接,您不应依赖它。

于 2012-09-04T11:21:38.827 回答
1

过去我在使用 INDY 时遇到过同样的问题(使用 D6 时,1998-2000 年)。我将组件更改为 IP*Works。当时它是一个外部组件,但据我所知,它包含在 XE2 中。Ip*Works 一开始有点难以理解,但他们处理通信结构的方式却大不相同。

我认为值得一试。

于 2012-09-06T12:21:59.153 回答