首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >TIdTCPClient忽略ReadTimeout

TIdTCPClient忽略ReadTimeout
EN

Stack Overflow用户
提问于 2022-10-17 19:30:03
回答 1查看 67关注 0票数 0

我使用TIdTCPClient发送消息并收到答复。我的消息和答案结构相当好,这意味着它们可以有不同的长度,但总是以#FS字符结尾。

我的Delphi (Alexandria)代码如下所示:

代码语言:javascript
复制
_TcpClient := TIdTCPClient.Create(Self);
_TcpClient.ReadTimeout := 60000;
_TcpClient.ConnectTimeout := 30000;
_TcpClient.Host := X.X.X.X;
_TcpClient.Port := Y;

然后我发出我的信息:

代码语言:javascript
复制
_TcpClient.Connect;
_TcpClient.IOHandler.Write(messageText);

最后,我等待另一方用ACK确认消息(正如我所说,以#FS结束):

代码语言:javascript
复制
try
  ans := TStringStream.Create;
  repeat
    b := _TcpClient.IOHandler.ReadByte;
    ans.Write(b,1);
  until b = #FS;
  b := _TcpClient.IOHandler.ReadByte;
  ans.Write(b, 1);
except
  _status := ssAckTimeout;
end;

所有这些都能很好地应用于短消息,但对于互联网上较大的短信(大约100 K),这一切都失败了。

最后一段代码在8-10秒后落入except部分,没有读取任何内容。

我对组件工作方式的理解是,它应该逐字节读取,等待ReadTimeout#FS。我不知道为什么它会忽略我的ReadTimeout值,只需8秒就会失败。

有没有人知道答案,或者能提出解决方案?

EN

回答 1

Stack Overflow用户

发布于 2022-10-17 20:38:55

IOHandler.ReadByte()方法确实尊重ReadTimeout属性,尽管您声称它没有。唯一可能比预期早引发错误的方法是,如果操作系统的套接字堆栈中存在缺陷。

但是,您的代码中存在一个潜在的缺陷。循环读取直到#FS到达并写入ans,然后再尝试读取超过#FS的一个字节。除非您的消息实际上有这样一个跟踪字节(可能是校验和?),否则这将失败并破坏您的通信。

在任何情况下,与循环中调用ReadByte()不同,一个更简单的解决方案是使用IOHandler.ReadLn()方法,指定#FS作为分隔符来结束行,例如:

代码语言:javascript
复制
var
  ans: string;
...
ans := _TcpClient.IOHandler.ReadLn(#FS);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74102289

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档