gpt4 book ai didi

delphi - Indy TIdTCPClient 组件偶尔不超时,收不到数据

转载 作者:可可西里 更新时间:2023-11-01 02:33:08 26 4
gpt4 key购买 nike

我正在使用 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 服务的发布者已经响应。他们承认了自己的问题并解决了其中的一些问题。我们不再超时。大多数回复会在大约 2 秒内收到,少数回复会稍长一些。发布者正在努力解决剩余的问题。

谢谢大家的意见。

最佳答案

您需要运行 Fiddler2 并观察流量。它将自己作为代理插入并嗅探使用 WinInet 堆栈的一切。然后你就会知道你是否得到了任何数据,以及你发送和接收的确切内容。 http://www.fiddler2.com/fiddler2/

关于delphi - Indy TIdTCPClient 组件偶尔不超时,收不到数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6507558/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com