【问题标题】:TCP connection timeout is 20 or 21 seconds on *some* PCs when set to 500ms当设置为 500 毫秒时,*某些* PC 上的 TCP 连接超时为 20 或 21 秒
【发布时间】:2012-08-17 10:31:18
【问题描述】:

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

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

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

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

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

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

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

【问题讨论】:

  • 随机猜测 - 检查 DNS 如何在这些不同的 PC 上运行。
  • 在盒子上运行wireshark,看看发生了什么
  • 为您节省一点时间 - wireshark.org
  • 为什么要拉网线?你也可以尝试连接一个无效的IP地址,结果应该是一样的!拉线不会自动触发“重新连接”,只有应用代码可以做到这一点。
  • @Mawg IIRC "ReadTimeout" 表示每个字节读取之间的毫秒数是允许的最大时间,500 相当多,我会选择更低的。

标签: delphi tcp indy10


【解决方案1】:

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

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

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

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

【讨论】:

  • 啊啊!叹。看来我是时候学习如何穿线了。大概每个线程都会创建一个 TCP 客户端,发送消息(它作为参数接收),获得回复或捕获异常,然后将 Windows 消息发送到带有结果的主窗体并销毁 TCP 客户端?嗯,我可以得到一个唯一的线程ID来追踪海豚吗?
  • 谢谢,@David 我现在正在潜入线程世界 ;-)
  • close 放在不同线程中的问题在于绑定的生命周期管理。如果工作线程正在关闭套接字,则在完成之前您无法释放绑定。
  • Indy 确实使用工作线程来建立连接,如果线程在超时之前没有终止,那么 Indy 会关闭套接字并等待线程终止。您是否建议 Indy 使用 another 线程来关闭套接字?我想 Indy 可以创建一个线程但不等待它,只是让它在后台运行并在完成后自行终止。这将需要TIdSocketHandle 放弃套接字句柄的所有权,并在准备好时将其交给线程以释放...
  • ... 但是仍然存在 Indy 必须等待连接线程终止的问题,如果它仍在等待关闭线程实际关闭套接字,这并不能解决任何问题.
【解决方案2】:

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

我认为值得一试。

【讨论】:

  • 有时间我会试一试的。感谢您的提示(尽管乍一看,我没有在 XE2 中看到它)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-10-03
  • 1970-01-01
  • 1970-01-01
  • 2023-03-09
  • 2016-03-01
  • 2020-10-25
  • 1970-01-01
相关资源
最近更新 更多