I am trying to make use of Borlands TClientSocket
component in non-blocking mode inside a multithreaded C++ Windows application. I am creating multiple threads (classes derived from TThread
), each of which creates its own TClientSocket
object. I then assign member functions of the thread class to act as event handlers for the OnConnect
, OnDisconnect
and OnSocketError
events of the socket. The problem I am having here is that whenever I call the TClientSocket::Open()
function from within the TThread::Execute()
function, the OnConnect
event never fires. However, When I call the Open()
function from the VCL thread prior to the TThread::Execute()
function getting called, all of the events fire and I can use the thread-socket combination as I would like. Now I have not read anything in documentation that says that TClientSocket
should not be used in non-blocking mode when used inside a thread, but it appears to me that there is perhaps something wrong conceptually in the way I am trying to use this class. Borland documentation is quite poor on the subject and these components have now been deprecated so reliable information is hard to come by. Despite being deprecated I have to use them as there is no alternative in the Builder 6 package I have. Can anyone please advise me if there is a right/wrong way to use TThread
and a non-blocking TClientSocket
in combination. I have never had problems using it as part of the VCL thread and never had problems using TServerSocket before and I really cannot understand why some events are not firing.
TClientSocket
in non-blocking mode uses a hidden window internally to receive socket events. If you use a non-blocking TClientSocket
in a TThread
then you must implement a message loop inside of your TThread::Execute()
method in order to dispatch those messages to the socket's window. Also, being window-based, that also means that the socket messages are sent to the thread that actually creates the socket window, so you have to make sure you are opening the TClientSocket
from inside of your TThread::Execute()
method.
BTW, BCB6 shipped with Indy 8, which is an alternative. You can also install an up-to-date version of Indy, or even another third-party library like ICS or Synapse.