Marlon Tiedt Marlon Tiedt - 1 month ago 12x
C# Question

TClientSocket in Delphi persistent connection

I have an application written in Delphi using

that is sending data to another application written in C#. For many reasons, the C# application is slow to respond, blocking my Delphi application and not respecting the time-out I have set.

My Delphi application reads responses like this:


This causes the application to wait for a response. But if I do this instead, the application waits and respects the time-out:

while not receiveData do
if Sock.Socket.ReceiveLength > 0 then
receiveData := True;

if (Cont > 10) then
raise Exception.Create('Timeout');

My Delphi app sends two requests. The first one times out, but C# is still processing it. My Delphi app then sends the second request, and this time C# sends the response for the first request.

Will the second request receive data for the first request? Or, when I timeout in Delphi, will they cross information?


Once your Delphi code times out, it forgets about the first request, but your C# code does not know that. Since you are not dropping the connection, the second request will indeed receive the response data for the first request. By implementing timeout logic and then ignoring the cause of the timeout, you are getting your two apps out of sync with each other. So, either use a longer timeout (or no timeout at all), or else drop the connection if a timeout occurs.

As for your Delphi app freezing, that should only happen if you are using the TClientSocket component in blocking mode and performing your reading in the context of the main UI thread. You should not be using blocking mode in the main UI thread. Either:

  1. Use TClientSocket in non-blocking mode, do all of your reading in the OnRead event only, and do not read more than ReceiveLength indicates.

  2. Use TClientSocket in blocking mode, and do all of your reading in a worker thread, and then signal the main UI thread only when there is data available for it to process (better would be to process the data in the worker thread, and only sync with the main thread when making UI updates).