IndySockets / Indy

Indy - Internet Direct
https://www.indyproject.org
434 stars 147 forks source link

Tidtelnet.Disconnect cannot be disconnected #524

Closed lzplzp001 closed 4 months ago

lzplzp001 commented 4 months ago

IdTelnet1.Disconnect(); IdTelnet1.Connect; //If Tidtelnet is already connected, using Tidtelnet .Disconnect does not disconnect, resulting in an error message when using Tidtelnet.Connect again.

I see TIdTCPConnection.pas in idTCPConnection.Disconnect calls DisconnectNotifyPeer, but there is no code in DisconnectNotifyPeer

rlebeau commented 4 months ago

DisconnectNotifyPeer() is intentionally empty at the TCP level. It is a virtual method, various protocol-specific descendants override it when they need to send messages to peers while closing connections. But there is nothing in the Telnet protocol to notify a peer about when closing the connection, which is why TIdTelnet does not override DisconnectNotifyPeer(). TIdTelnet overrides Disconnect() itself instead, to shut down its internal reading thread while closing the connection.

Typically, the only way that Connect() would think the socket is already connected after a Disconnect() is if there is unread data left behind in the IOHandler's InputBuffer. Even though the physical socket has been closed, Indy will still allow reads to succeed until the InputBuffer is exhausted. This is by design.

So, to make sure the connection is fully closed, try clearing the InputBufer before calling Connect() again, eg:

IdTelnet1.Disconnect;
if Assigned(IdTelnet1.IOHandler) then
  IdTelnet1.IOHandler.InputBuffer.Clear; // <-- ADD THIS
IdTelnet1.Connect;
lzplzp001 commented 4 months ago

Thank you! According to the code you provided, it worked!