如何完全断开TCPClient连接?(Indy)

16

当我的Tcp客户端在运行时,使用以下代码:

TCPClient.Disconnect;
TCPClient.Connect;

我收到一个异常,其类为"EIdAlreadyConnected",错误消息为"Already connected.",但我之前已经断开了连接,为什么还是会出现这个错误?

那么,我该如何完全断开连接呢?

谢谢。

3个回答

20

当使用 Indy 10 时,您必须确保输入缓冲区为空。

if idTcpClient.connected then
begin
 idTcpClient.IOHandler.InputBuffer.clear;
 idTcpClient.Disconnect;
end;

8
Connected()方法在判断连接是否仍然开启时,即使物理套接字已关闭,只要输入缓冲区仍有未读数据可以满足读取请求而不必返回到套接字,该连接仍被视为打开状态。这是经过设计的。通常,您只有在读取连接提供的所有数据后才会断开套接字。如果您提前断开连接,则必须通过清除输入缓冲区中已接收但未读取的数据来手动清除。 - Remy Lebeau
请确保没有设置 "LINGER" 套接字选项。 - Marco van de Voort
2
在断开连接之后,难道不应该清除缓冲区吗?因为假设在清除和断开连接之间它接收到一些数据呢? - Jerry Dodge
我也想知道示例中的顺序是否正确(先清除,然后断开连接)? - StanE
顺序应该被倒转,我今天遇到了这个问题。(Delphi XE5) - Wodzu
据我记得,如果您不关心缓冲区,那么在断开连接之前应该清除缓冲区,但是Indy可能已经纠正了这个问题,因为我为Delphi 7编写了此解决方案,而我记得的Indy版本是9。 - sabri.arslan

2

您说它已经断开连接,但是您只是给出了断开命令。

网络流量需要时间,可能在您真正断开之前就已经重新连接了。

可能您需要监控一些连接状态或事件,等待直到您真正断开。

... 或者尝试处理异常并忽略它,使用try..except


1
Indy不使用异步通信,因此直觉会认为当命令返回时,它已经完成了其工作。 - jpfollenius
问题在于工作的定义。需要发送断开连接,或者确认/超时以完全关闭它。 - Marco van de Voort

1
TCPClient.IOHandler.InputBuffer.Clear;
TCPClient.IOHandler.CloseGracefully;
TCPClient.Disconnect;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接