aehimself 399 Posted September 25, 2020 (edited) 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 September 25, 2020 by aehimself Share this post Link to post
FPiette 385 Posted September 25, 2020 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
aehimself 399 Posted September 25, 2020 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
FPiette 385 Posted September 26, 2020 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
Angus Robertson 577 Posted September 26, 2020 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
aehimself 399 Posted September 26, 2020 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
Angus Robertson 577 Posted September 27, 2020 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
aehimself 399 Posted September 27, 2020 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
Angus Robertson 577 Posted September 27, 2020 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