Need to send data from TServersocket to TidTcpClient

623 views Asked by At

I'm using Delphi XE8 for developing mobile apps and Desktop application. In mobile application, I'm using TIDtcpClient component and in Desktop application application, I'm using TServerSocket.

Server Desktop application contains TList which contains some 1500 records. For getting these values in Client Mobile application, I'm using the following method.

  1. First the download request is send from Client mobile app to Server application.
  2. Next it retrieves 10 records and sends back to Client mobile application. After this it updates the values in Client List and then again it sends back the request to server app.
  3. Till the record count reaches, this process continues.

The problem is when I'm following this method it takes almost 2 minutes of time and I'm getting all the data properly. So I have decided to use the file stream method. Below I have mentioned the sample code:

Server Side app:

//first saved the List into FileStream & it is working as I have reloaded and checked
//So again I'm loading the saved file, The file Size is near to 400KB
FileStream := TFileStream.Create('D:\ListDet.dat', mtfmOpenRead);
Socket.SendStream(FileStream);

Client Side mobile app:

var 
  FileS: TFileStread;
  i: Size;
begin
//Inside the thread
  TiDTcpClient.IOHandler.ReadStream(FileS, i);
end;

And When I'm using the above method, I'm getting the exception and I'm can not retrieve data.

Please provide me any solution to retrieve the data faster from Server to Client.

1

There are 1 answers

0
Remy Lebeau On BEST ANSWER

The problem is when I'm following this method it takes almost 2 minutes of time and I'm getting all the data properly.

You did not show/explain what actual I/O methods you were using to send the data in that situation.

So I have decided to use the file stream method ... And When I'm using the above method, I'm getting [Closed gracefully exception in Client app (Mobile)] and I'm can not retrieve data

TCustomWinSocket.SendStream() simply sends the content of the TStream as-is, it does not send anything else.

You are passing an uninitialized variable, i, to TIdIOHandler.ReadStream(). That parameter tells ReadStream() how many bytes to read. Since i is uninitialized, its value is whatever random data happens to be on the stack at that moment.

If i happens to be > 0 at runtime, that is how many bytes ReadStream() will try to read. If that many bytes are not actually sent, ReadStream() will block the calling thread waiting for more bytes until its ReadTimeout elapses (which is infinite by default) or the socket is disconnected.

If i happens to be exactly -1 (and the AReadUntilDisconnect parameter is False by default), ReadStream() will try to read an Integer/Int64 (depending on the TIdIOHandler.LargeStream property) from the socket and use that as the byte count to finish reading the rest of the stream. TCustomWinSocket.SendStream() is not sending any such size value.

If i happens to be < 0, ReadStream() will simply ignore the byte count and just keep reading until the socket is disconnected (AReadUntilDisconnect is forced to True).

The default behavior of TIdIOHandler.ReadStream() is to expect the stream data to be preceded by the stream size, but you are overriding that behavior by passing the uninitialized i variable, so the behavior is undefined.

Your server is not sending the stream size before sending the stream data, so the client has no way of knowing how many bytes to expect, unless you disconnect the socket after sending the stream.