我正在使用Internet Direct TIdTCPClient组件与远程服务进行通信,以检索通常大小约为5k的邮件。在典型操作期间,我将向服务发送大约400个请求,每个请求大约需要1秒钟才能完成。大多数时候一切都很完美。但是,大约百分之一的时间请求需要189秒,而我根本没有收到任何数据。为了便于讨论,我将其称为失败。
我特别想知道发生故障时到底发生了什么,以便我可以将我的证据带给服务的发布者。首先,失败是不可重复的。如果我重新发送失败的请求,那么它的可能性很高(可能是99%)。
我还捕获了发生故障时发送的请求,因此我能够确认请求是否格式良好。
我假设在失败期间我得到了一些数据,而不是全部。这就是原因。我的IdTCPClient有30秒超时(我甚至将它设置为5秒,但这没有什么区别)。当故障发生时,它总是在189秒(加上约500毫秒)后失败。
因此,我认为在故障期间我的组件正在接收涓流的数据,这就是我的客户端没有超时的原因。并且,我假设在服务中发生断开连接,因为我的超时值都没有设置为189秒。另一方面,读取IOHandler.AllData不会引发异常(甚至不会引发EIdConnClosedGracefully异常)。我是否正确地解释了这些证据?
我想要做的是在服务终止连接之前确认我正在获取一些数据,而不是全部数据。此外,我想知道部分数据是什么样的,因为我相信它可以帮助确定失败的根源。
目前,我的请求类似于以下内容:
//ExceptionName is a temporary global variable
//that I am using while trying to solve this issue
ExceptionName = 'no exception';
try
s := GetRequest(id);
IdTcpClient1.Host := Host;
IdTcpClient1.Port := StrToInt(Port);
IdTcpClient1.ReadTimeout := ReadTimeout;
try
IdTcpClient1.Connect;
except
on e: exception do
begin
ExceptionName := e.ClassName;
raise EConnectionFailure.Create('Connection refused: ' + e.Message)
end;
end;
IdTcpClient1.IOHandler.Writeln(s);
try
Result := IdTcpClient1.IOHandler.AllData;
except
on E: EIdConnClosedGracefully do
begin
ExceptionName := e.ClassName;
//eat this exception
end;
on e: Exception do
begin
ExceptionName := e.ClassName;
raise;
end;
end;
finally
if IdTcpClient1.Connected then
IdTcpClient1.Disconnect;
end;
使用IOHandler.AllData读取数据非常方便,但是我无法在失败后检索任何数据(AllData返回一个空字符串)。我在失败后测试了IOHandler.InputBufferIsEmpty,它返回True。
我还尝试过其他方法来读取数据,例如IOHandler.ReadStream(这会产生与读取AllData相同的结果)。我还使用了IOHandler.ReadBytes和IOHandler.ReadByte(与IOHandler.CheckForDataOnSource一起使用)。没有任何效果。
我对部分数据传输有误吗?如果是这样,为什么我会在失败前看到一致的189.nnnn秒延迟。
如果有可能进行部分数据传输,我应该采取什么方法来捕获失败前收到的每个数据字节。
我正在将Delphi 2009用于此项目和Indy 10,但我不认为该版本与它有任何关系。我不认为这是一个Indy问题。
编辑:我使用WireShark检查了我的Indy客户端和服务器之间的通信。当其中一个故障发生时,在发送我的请求后,服务器发送两个[ACK]数据包,然后静音超过189秒。在该延迟之后,响应包括[FIN,PSH,ACK]但没有应用程序数据。
当通信正常工作时,服务器响应我的请求返回的两个ACK数据包之后是应用程序数据包。
编辑:已向Web服务的发布者报告了该问题,我正在等待回复。
编辑:好的,Web服务的发布者已经回复了。他们承认自己的问题并解决了其中的一些问题。我们不再获得超时。大多数响应在大约2秒内收到,少数响应时间稍长。发布商正在努力解决剩余的问题。
感谢大家的意见。
答案 0 :(得分:1)
您需要运行Fiddler2并观察流量。它将自身作为代理插入并嗅探使用WinInet堆栈的外观。 然后你知道你是否有任何数据,以及你发送和接收的确切内容。 http://www.fiddler2.com/fiddler2/