Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: Cannot disconnet tIdTcpClient


This question is answered. Helpful answers available: 0. Correct answers available: 1.


Permlink Replies: 3 - Last Post: Jan 16, 2015 10:00 AM Last Post By: Remy Lebeau (Te...
Poul Kristensen

Posts: 7
Registered: 9/27/00
Cannot disconnet tIdTcpClient  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 15, 2015 6:21 AM
Hi

tIdTcpClient.Disconnect() does not seem to work.
Seems to work okay, but when I try to send again, I get an "Alrready connected" error.
Do I have to create a new tIdTcpClient for every communication?
I have XE5.

Poul

Edited by: Poul Kristensen on Jan 15, 2015 7:46 AM
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Cannot disconnet tIdTcpClient [Edit]
Helpful
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 15, 2015 8:57 AM   in response to: Poul Kristensen in response to: Poul Kristensen
Poul wrote:

tIdTcpClient.Disconnect() does not seem to work.

It works fine.

Seems to work okay, but when I try to send again, I get an
"Alrready connected" error.

Connect() calls Connected() internally and raises that error if Connected()
returns True.

Connected() returns True if either:

1. the socket is still connected to the server.

2. the socket is not connected, but the IOHandler is assigned and its InputBuffer
has unread data in it.

The latter case usually happens if you have assigned your own IOHandler (otherwise
Connect() creates its own IOHandler and Disconnect() frees it), and you experience
an error during your communications that prevents you from reading everything
you have received from the server. Under normal communication conditions,
you would read everything before disconnecting.

Do I have to create a new tIdTcpClient for every communication?

No. After calling Disconnect(), if the IOHandler is not nil then call its
InputBuffer.Clear() method before calling Connect() again, eg:

tIdTcpClient.Disconnect;
if tIdTcpClient.IOHandler <> nil then tIdTcpClient.IOHandler.InputBuffer.Clear;


--
Remy Lebeau (TeamB)
Poul Kristensen

Posts: 7
Registered: 9/27/00
Re: Cannot disconnet tIdTcpClient [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 16, 2015 2:48 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Remy Lebeau (TeamB) wrote:
Poul wrote:

tIdTcpClient.Disconnect() does not seem to work.

It works fine.

Seems to work okay, but when I try to send again, I get an
"Alrready connected" error.

Connect() calls Connected() internally and raises that error if Connected()
returns True.

Connected() returns True if either:

1. the socket is still connected to the server.

2. the socket is not connected, but the IOHandler is assigned and its InputBuffer
has unread data in it.

The latter case usually happens if you have assigned your own IOHandler (otherwise
Connect() creates its own IOHandler and Disconnect() frees it), and you experience
an error during your communications that prevents you from reading everything
you have received from the server. Under normal communication conditions,
you would read everything before disconnecting.

Do I have to create a new tIdTcpClient for every communication?

No. After calling Disconnect(), if the IOHandler is not nil then call its
InputBuffer.Clear() method before calling Connect() again, eg:

tIdTcpClient.Disconnect;
if tIdTcpClient.IOHandler <> nil then tIdTcpClient.IOHandler.InputBuffer.Clear;


--
Remy Lebeau (TeamB)

Hi Remy

Your solution sounds very plausible. But it does not seem to be the entire truth.
Check this picture
http://www.maagaard.dk/Figs/fig.png

I clear the InputBuffer and then check if the IdTcpClient is still connected and not only does the IdTcpClient still exists, it's still connected.
If you then check the Watch list, you can see that there is still apparently 1 byte data (FSize = 1) left, but the list is actually empty (FBytes = 0) (I may be misunderstanding the names of some of these variables).
So I do a InputBuffer.Clear, but it doesn't work.

To me, there still seems to be something wrong. But your answer is good, and I made a work around, so it's not important any more, just annoying.

Thanks and best regards

Poul
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Cannot disconnet tIdTcpClient [Edit]
Helpful
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 16, 2015 10:00 AM   in response to: Poul Kristensen in response to: Poul Kristensen
Poul wrote:

I clear the InputBuffer and then check if the IdTcpClient is still
connected and not only does the IdTcpClient still exists, it's still
connected.

If you then check the Watch list, you can see that there is still
apparently 1 byte data (FSize = 1) left, but the list is actually
empty (FBytes = 0) (I may be misunderstanding the names of some
of these variables).

If you look at the implementation of TIdBuffer.Clear(), it sets FBytes to
nil and FSize to 0:

procedure TIdBuffer.Clear;
begin
  SetLength(FBytes, 0); // <-- FBytes := nil
  FHeadIndex := 0;
  FSize := Length(FBytes); // <-- FSize := 0
end;


In your screenshot, FBytes itself is not 0, it is *FBytes that is 0. That
combined with FSize being 1 means that FBytes contains a null byte ($00).
Also, your screenshot shows the IDE stopped on a breakpoint on the call
to InputBuffer.Clear(), which means the InputBuffer has not actually been
cleared yet. Move your breakpoint down to the Connected() call, and you
should see different results.

--
Remy Lebeau (TeamB)
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02