我正在开发一个使用套接字与各种设备通信的旧版 VB6 应用程序。在 2012 系统上,我们注意到调用 winSock.Connect 到被触发的连接事件之间的时间大约为 9 秒,跨越不同域的多个系统。在 2008 R2 或更低版本的系统上,调用和触发事件之间的时间为 1-3 毫秒。
以前有没有人遇到过这种情况,或者对可能导致这种情况的原因有任何想法?
谢谢
编辑:我用 Wireshark 进行了一些窥探,发现前几个 TCP 传输没有连接并被重新传输,不确定这是否有帮助
我正在开发一个使用套接字与各种设备通信的旧版 VB6 应用程序。在 2012 系统上,我们注意到调用 winSock.Connect 到被触发的连接事件之间的时间大约为 9 秒,跨越不同域的多个系统。在 2008 R2 或更低版本的系统上,调用和触发事件之间的时间为 1-3 毫秒。
以前有没有人遇到过这种情况,或者对可能导致这种情况的原因有任何想法?
谢谢
编辑:我用 Wireshark 进行了一些窥探,发现前几个 TCP 传输没有连接并被重新传输,不确定这是否有帮助
Winsock 控件没有什么特别“特别”的地方,它只是 API 之上的一个薄包装器。唯一需要注意的是它是 32 位的,必须在 WOW64 中运行。
您可能正在做一些有趣的事情,或者所有使用 winsock API 的 32 位程序以同样的方式应该看到同样的问题。
也许您在此服务器上有名称解析问题?
经过一番广泛的挖掘,我最终找到了答案。
从 Windows Server 2012 开始,Microsoft 启用了称为显式拥塞通知 (ECN) 的 TCP 扩展。这允许在丢包的情况下端到端通知网络拥塞。在 TCP 数据包上启用此功能的方式是通过一个标志,该标志在 ECN 的定义 (RFC 3168(2001)) 中定义。
对我来说发生的事情是我的应用程序与之通信的设备较旧,并且不支持 ECN 标志。当他们收到启用了该标志的数据包时,他们不会确认传输,从而导致服务器超时。在两次传输失败后,Windows 似乎关闭了 ECN 标志,并且设备确认了数据包。
我禁用了从管理员命令提示符运行以下命令的 ECN:
netsh interface tcp set global ecncapability=disabled