Windows Socket#10060错误(WSAETIMEDOUT-在未建立连接的情况下尝试连接超时)是否可能是编程错误?
我有一个Delphi应用程序,它使用Indy HTTP组件(使用Windows套接字)。在执行Indy过程时,我不时收到#10060套接字错误(WSAETIMEDOUT-连接尝试在未建立连接的情况下超时):Windows Socket#10060错误(WSAETIMEDOUT-在未建立连接的情况下尝试连接超时)是否可能是编程错误?,windows,sockets,delphi,indy,indy10,Windows,Sockets,Delphi,Indy,Indy10,我有一个Delphi应用程序,它使用Indy HTTP组件(使用Windows套接字)。在执行Indy过程时,我不时收到#10060套接字错误(WSAETIMEDOUT-连接尝试在未建立连接的情况下超时): CheckForSocketError(IdWinsock2.Connect(ASocket, @LAddr, SizeOf(LAddr))); ... connect : TconnectProc; ... TconnectProc = function ( const s: TSocke
CheckForSocketError(IdWinsock2.Connect(ASocket, @LAddr, SizeOf(LAddr)));
...
connect : TconnectProc;
...
TconnectProc = function ( const s: TSocket; const name: PSockAddr; const namelen: Integer): Integer; stdcall;
实际上,所有这些都只是环绕Windows connect函数,它给出错误和消息WSAETIMEDOUT。所以-我的问题是-这可能是编程错误吗?即使我在另一台计算机上运行服务器,即使该服务器在服务请求时出现问题,即使在这种情况下,低级连接也应正常执行,如果服务器无法服务GET/POST请求,那么,当然,错误应该是,但这些错误应该只在执行其他套接字函数时出现,而不是在connect
函数中,不是吗
我试图解决我的问题,现在我正在寻找我的代码中发生了什么
我的服务器端代码非常简单-它只是实现了的TIdHttpServer组件(我仅在此处提供事件名称):
那么-我的实现有什么问题,是什么导致了WSAETIMEDOUT
forconnect
的出现?是的,我的过程有时会很长,但多年来,它成功地返回了答案,并且没有通信错误。我猜,连接函数甚至不能依赖(不使用/引发)OnCommandGet事件,因此,我无法控制服务器端如何处理来自客户端的套接字连接函数
这可能是与TCP(而非HTTP)keepalive连接的,可能一些Windows更新减少了客户端的Windows TCP keepalive设置,现在这显示为这样的错误。Indy TCP客户端,如
TIdHTTP
,有一个公共ConnectTimeout
属性,该属性设置为0(无限)默认情况下。如果未指定超时,则如果在主UI线程中调用了客户端的TIdTCPClient.Connect()
方法并且tidAntizone
处于活动状态,则使用硬编码的2分钟超时,否则不使用超时
如果使用超时,Indy将在工作线程中调用Winsock的connect()
函数,并等待该线程终止。如果Indy超时,则关闭套接字以中止connect()
,然后将EIdConnectTimeout
发送给调用方。如果connect()
在Indy的超时时间过去之前退出,则仅当connect()
失败时才会向调用方引发异常
如果未使用超时,Indy将直接调用Winsock的connect()
,等待它自动退出,然后仅在失败时才会引发异常
因此,当Indy调用Winsock的connect()
函数时,您可以从Indy获得WSATIMEDOUT
错误的唯一方法是Winsock本身在Indy自身超时之前在内部超时。这并不一定表明代码中存在问题。这只意味着此时无法连接到您试图连接的主机。如果可以访问服务器,但无法接受您的连接,则会出现另一个错误,例如WSAECONNREFUSED
如果您的服务器位于防火墙或路由器后面,请确保它没有阻止连接到您的服务器。尝试在服务器计算机(如WireShark)上运行数据包嗅探器,并确保来自
TIdHTTP
的三方TCP握手正确到达服务器计算机。这正是我的情况-我们的网络受到外部攻击,中央防火墙主动阻止了此类连接,但是防火墙也删除了我在问题中提到的客户端软件的合法流量/连接。因此-在阻止攻击IP地址并停止传入的攻击流量后,防火墙恢复了regulat活动,并且#10060错误也消失了。所有这些都可以从防火墙日志中看到,因此,如果出现此类低级套接字错误,最好检查防火墙或防病毒日志。
MyForm.IdHTTPServerCommandGet(AContext: TIdContext;
ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);