1

I am writing a C++ application using Embarcadero RAD studio and TServerSocket component in blocking mode. I have overridden the OnGetThread handler for the socket to create a custom class derived from TServerClientThread which overrides the default ClientExecute() method. Within this function I use a TWinSocketStream and make calls to WaitForData(), Read(), and Write() to receive and send data. According to everything I have read this is an acceptable way to go about things (although please correct me if this is wrong).

From this answer What events are fired for a blocking socket? I am lead to believe that using an OnClientError handler in blocking mode is OK since the events will fire. In my event handler I set the error code to zero every time so that the exception does not get thrown.

In addition, every time I call Read() or Write() from within my ClientExecute() function I wrap it in a try-catch block and catch ESocketError exceptions.

My question is this: Which is the best approach:

  1. Use a socket error event handler to deal with everything (this is nice as I can get the socket error code to display for debugging purposes)
  2. Use the try-catch statements to prevent my application from throwing exceptions
  3. Use both (although not set the error code to zero in the handler otherwise the exception will not get thrown making 2. above pointless)

This is an old component and has been deprecated but I have to use this but as I have been unable to find a cast iron guide to using it correctly I have pieced together an approach from many sources. It has been working well for quite some time, but every now and again I get a silent error which prevents the server from accepting any further client connections - but I get no output from OnClientError and no ESocketErrors are thrown. This application is running on an embedded device so the only way it is detected is when it becomes non-responsive.

If anyone could give me advice on which of the 3 approaches above is best (or suggest an alternative) I would be very grateful.

Community
  • 1
  • 1
mathematician1975
  • 21,161
  • 6
  • 59
  • 101
  • IIRC, I just caught exceptions, though it was some time ago. I think that OnClientError would get called in the context of the TServerClientThread anyway and so the error data would require PostMessaging, (or, if you're feeling suicidal, TThread.Synchronize), to the GUI anyway. – Martin James Apr 09 '13 at 12:12
  • @MartinJames I dont want to display the error just log it so I dont need to sync with the VCL thread. I just want to know what the error was. The documentation is poor so I don't know whether to just try catch all my Read and Write calls and dump the event handler. – mathematician1975 Apr 11 '13 at 13:19

1 Answers1

2

If TServerSocket is not accepting new connections anymore, then either its internal TServerAcceptThread thread has crashed so TServerWinSocket.Accept() is not being called anymore, or else Accept() is being called but is encountering OS errors (lack of system resources, etc). Either way, TServerSocket does not expose any kind of error information from those particular areas of its code, so you have no way of detecting and handling when your server stops accepting connections, unless your connections are frequent enough that you can use a timer to detect long runs of inactivity between OnClientConnect events. If you suspect your server has entered a non-accepting state, all you can do is have your app close and re-open the TServerSocket.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • The strange thing is that my `OnclientConnect` event never fires. `OnAccept` and `OnDisconnect` fire but not `OnConnect`. I cannot help but think maybe I have got things set up incorrectly. I have ensured all my handlers are thread safe. I am really not sure – mathematician1975 Apr 11 '13 at 13:24
  • Nor does the `OnClientError` event handler. Is there anything I have to do to allow the event handler to fire. Or should I remove them all and just try-catch around all Read()/Write() calls in the TServerClientThread::ClientExecute() function ? – mathematician1975 Apr 11 '13 at 14:00