Jump to content
aehimself

TWClientSocket OnConnect & OnDisconnect handlers?

Recommended Posts

Hello,

 

I'm in the process to migrate an old code from TClientSocket to an ICS TWSocket. All seems to work fine, except the OnConnect & OnDisconnect handlers.

 

Create a new VLC project, with a TWSocket and a memo on it and use the following code:

Function SocketStateToString(Const inSocketState: TSocketState): String;
Begin
 Case inSocketState Of
  wsInvalidState: Result := 'invalid';
  wsOpened: Result := 'opened';
  wsBound: Result := 'bound';
  wsConnecting: Result := 'connecting';
  wsSocksConnected: Result := 'socks connected';
  wsConnected: Result := 'connected';
  wsAccepting: Result := 'accepting';
  wsListening: Result := 'listening';
  wsClosed: Result := 'closed';
  wsDnsLookup: Result := 'DNS lookup';
  Else Result := 'unknown';
 End;
End;

procedure TForm3.FormCreate(Sender: TObject);
begin
 WSocket1.Connect;
end;

procedure TForm3.WSocket1ChangeState(Sender: TObject; OldState,
  NewState: TSocketState);
begin
 Memo1.Lines.Add('State change from ' + SocketStateToString(OldState) + ' to ' + SocketStateToString(NewState));
end;

procedure TForm3.WSocket1SessionClosed(Sender: TObject; ErrCode: Word);
begin
 Memo1.Lines.Add('Session closed');
end;

procedure TForm3.WSocket1SessionConnected(Sender: TObject; ErrCode: Word);
begin
 Memo1.Lines.Add('Session connected.');
end;

Set the WSocket's Addr to 127.0.0.1 and the port to 1024. Make sure no application listens.

 

When I run the above code, I get the following result:

 

State change from closed to opened
State change from opened to connecting
State change from connecting to connected
Session connected.
State change from connected to closed
Session closed
 

The state goes to connected for a brief moment, also session is connected... to nothing (?) before both goes back to closed.

 

What is the normal place to put my code in, which is granted to run ONLY if the socket was really connected and disconnected?

 

Edit: I'm using ICS vV8.64 on Delphi 10.4.1

Edited by aehimself

Share this post


Link to post

Maybe the server you connect to wait for some request. If nothing comes within a given time, then the server close the connection.

 

In your code, you should add an OnDataAvailable handler to read incoming data and display it.

 

Why not first try one of the client demos provided with ICS distribution?

 

Share this post


Link to post

That's the trick. There is NOTHING listening on that port - therefore no data to be received. The result is the same if I set the addr to '99.88.77.66' or other nonsense - I expect nothing to be there. This is why I said:

38 minutes ago, aehimself said:

Make sure no application listens.

 

Share this post


Link to post

You should display the ErrCode argument in OnSessionConnected event handler. I'm sure it is something like 10061. If the connection is successful, then the ErrCode is zero. Same for OnSessionClosed.

OnSessionClosed is immediately called when the connection fails. So what you see is normal behavior.

Share this post


Link to post

The OnSessionConnected event and state wsConnected really mean async connection attempt finished, either successfully or failed according to the error code, it may not be triggered for 30 seconds or more with TCP timeouts.  Connecting to a local port not listening fails quickly. 

 

Every ICS async method results in a state change and one or more events being called when done, so you can decide what to do next, depending on what happened.  That is the major difference from using blocking TCP implementations that don't return until completed.   You can not use state alone to know when a connections succeeds. 

 

Angus

 

Share this post


Link to post
12 hours ago, FPiette said:

You should display the ErrCode argument in OnSessionConnected event handler.

And I seriously missed that, I just don't know how. Using the SessionConnected handler WITH a small check to the error code works - as designed I suppose 🙂

Let's hope that changing to a little bit more up-to-date component will solve the connectivity issues I had!

 

10 hours ago, Angus Robertson said:

You can not use state alone to know when a connections succeeds. 

This was the part I was missing; coming from an old, outdated component I expected the stateflow to be different if a connection attempt fails or succeeds. I was just unsure if I did something wrong in other parts of my code, or not.

I'm an ICS newbie. I'll learn 🙂

Share this post


Link to post

For a new application, you should look at the OverbyteIcsIpStmLogTst.dpr sample that uses TIcsIpStrmLog.  This is effectively a high level version of TWSocket that may be configured as a client or a server and hides most of the low level events and error handling from you, supports SSL/TLS and allows you to send lines or files, and receive from a single event, only needs a few lines of code for either.  Try the sample which will send data to itself.

 

Angus

Share this post


Link to post

Unfortunately, it seems to me that the error was not with the component after all. My current implementation of traffic handling seems to be correct, but I have exactly the same issue as with TClientSocket / TServerSocket. As it doesn't seem to be ICS-related, I opened a new topic for it:

 

Share this post


Link to post

If you use TIcsIpStrmLog. you won't need to be concerned about the low level receiving function, that is tried and tested in the component which provides you with packets or lines.

 

Angus

 

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×