c++socketsc++builderc++builder-xe

Why do OnClientConnect and OnClientError events not fire for TServerSocket in blocking mode


I am using Embarcadero RAD studio C++ builder XE to create a C++ application. The application uses a dynamically created TServerSocket component in blocking mode. I create a class derived from TServerClientThread which provides a custom ClientExecute() method. This class is created via the TServerSocket event handler OnGetThread which I have implemented. I assign event handlers for OnAccept, OnClientConnect, OnClientDisconnect and OnClientError. Inside my thread class I use TWinSocketStream class to read and write from the socket connection.

I use a custom written class (derived from TComponent) that creates the TServerSocket and the event handlers I assign are member functions of this class.

My OnAccept and OnClientDisconnect events fire but neither of the OnClientConnect and OnClientError events fire ever. Is this normal behaviour for this component? Everything I have read about this component suggests that ALL events will fire for TServerSocket in blocking mode and I simply cannot understand why these events will not fire. Is there anything further I am required to do or these events just not work in blocking mode? Is it possible that using the TServerSocket instance as a member of another TComponent derived class is causing some problem?


Solution

  • The OnClientConnect event is triggered by the TServerClientWinSocket constructor. A TServerClientWinSocket object is constructed immediately after the OnGetSocket event is called when a new client socket is accepted by WinSock, and right before the OnAccept and OnGetThread events are called. So the only possible way that OnClientConnect would not be called is if you do not actually have a handler assigned to it.

    OnClientError is called during non-blocking socket failures, and by TCustomWinSocket.SendStream(), TCustomWinSocket.SendBuf(), and TCustomWinSocket.ReceiveBuf(). If you use TWinSocketStream instead for your I/O, none of those methods are called by it. It raises ESocketError exceptions on failure instead. If you do not catch those exceptions, the calling TServerClientThread will simply terminate itself (after passing the exception to the main thread for handling).