德尔福/印地。 TIdStackWindows.Connect 过程出现长时间延迟

发布于 2024-12-12 23:09:39 字数 1085 浏览 0 评论 0原文

我的应用程序挂在对过程 TIdStackWindows.Connect 的调用中。当 TCP/IP 地址存在时,就没有问题,但如果不存在,我就会遇到困难。 IP 地址是一个文字 - 不涉及 DNS 查找。我预计连接尝试会在超时 (TCPClient.ConnectTimeout) 后失败,我设置了 1 秒,但应用程序在此调用中挂起长达 30 秒(来自我的应用程序的调用不是我打算将 TCP 连接移至线程,但长连接超时仍然是一个问题)。

如果当应用程序无响应时我在 Delphi IDE 中暂停执行,我会定位到:

ntdll.KiUserApcDispatcher:
7C90E450 8D7C2410         lea edi,[esp+$10]

然后按 F8 几次,直到看到堆栈帧。然后我在:

IdStack.TIdStack.RaiseSocketError(10038)
IdStack.TIdStack.RaiseLastSocketError
IdStack.TIdStack.CheckForSocketError(-1)
IdStackWindows.TIdStackWindows.Connect(912,'10.8.2.170',5001,Id_IPv4)
IdSocketHandle.TIdSocketHandle.Connect
IdIOHandlerStack.TIdConnectThread.Execute
:00451fc1 HookedTThreadExecute + $2D
Classes.ThreadProc($254B910)
System.ThreadWrapper($5456CB0)
:00451ea3 CallThreadProcSafe + $F
:00451f10 ThreadExceptFrame + $3C
:7c80b729 ; C:\WINDOWS\system32\kernel32.dll

经过一番探索后,我注意到这个主题已经收到了一些流量。常见的答案似乎是“把它放在一个线程中”。我打算这样做,但是长时间的超时仍然会出现问题。为什么连接超时不起作用?我正在使用 Indy 10.5.5 和 Delphi 2006 - 如果我升级到 Indy 的最新版本,是否会涉及大量迁移?

My app is hanging in the call to procedure TIdStackWindows.Connect. When the TCP/IP address exists there is no problem, but if it doesn't, I get the hang. The IP address is a literal- there is no DNS lookup involved. I was expecting the connection attempt to fail after the timeout (TCPClient.ConnectTimeout) I have set of 1 second but the app hangs for up to 30 seconds on this call (the call from my app isn't threaded. I intend to move the TCP connection to a thread, but the long connect timeout will still be an issue).

If I pause execution in the Delphi IDE when the app is unresponsive, I an positioned at:

ntdll.KiUserApcDispatcher:
7C90E450 8D7C2410         lea edi,[esp+$10]

I then F8 a couple of times until I see a stack frame. I am then at:

IdStack.TIdStack.RaiseSocketError(10038)
IdStack.TIdStack.RaiseLastSocketError
IdStack.TIdStack.CheckForSocketError(-1)
IdStackWindows.TIdStackWindows.Connect(912,'10.8.2.170',5001,Id_IPv4)
IdSocketHandle.TIdSocketHandle.Connect
IdIOHandlerStack.TIdConnectThread.Execute
:00451fc1 HookedTThreadExecute + $2D
Classes.ThreadProc($254B910)
System.ThreadWrapper($5456CB0)
:00451ea3 CallThreadProcSafe + $F
:00451f10 ThreadExceptFrame + $3C
:7c80b729 ; C:\WINDOWS\system32\kernel32.dll

I note after a bit of poking around that this topic has received a bit of traffic. The common answer seems to be "put it in a thread". I intend to, but the long timeout will still be problematic. Why does the connect timeout not work? I'm using Indy 10.5.5 and Delphi 2006 - if I upgrade to the latest build of Indy will there be much migration involved?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

幸福%小乖 2024-12-19 23:10:56

阻塞套接字在 API 层没有连接超时的概念,因此 Indy 的 ConnectTimeout 是手动实现的超时。 Indy 在内部工作线程中调用 TIdStack.Connect(),而 TIdTCPClient.Connect() 运行等待该线程终止的睡眠循环。如果循环检测到 ConnectTimeout 期限已过,它将关闭套接字,这应该会导致阻塞的 TIdStack.Connect() 立即退出,但这不是一个保证。创建和终止线程也会产生操作系统开销。对 1 秒超时做出反应绝对不应该花费 30 秒,但另一方面,1 秒通常太小了。线程甚至可能不会在 1 秒内开始运行。通常应将 ConnectTimeout 设置为至少 5-10 秒,以便为操作系统提供足够的时间来完成其工作。

Blocking sockets have no concept of a connect timeout at the API layer, so Indy's ConnectTimeout is a manually implemented timeout. Indy calls TIdStack.Connect() in an internal worker thread while TIdTCPClient.Connect() runs a sleep loop that waits for that thread to terminate. If the loop detects the ConnectTimeout period has elapsed, it closes the socket, which is supposed to cause the blocked TIdStack.Connect() to exit immediately, but that is not a guarantee. There is OS overhead in creating and terminating a thread as well. It should definitely not take 30 seconds to react to a 1 second timeout, but on the other hand 1 second is usually too small. It is possible that the thread will not even begin running within 1 second. You should typically set the ConnectTimeout to 5-10 seconds at a minimum to give the OS enough time to do its work.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文