* * *

Author Topic: [SOLVED] File exchange using indy.  (Read 213 times)

torbente

  • Full Member
  • ***
  • Posts: 205
[SOLVED] File exchange using indy.
« on: July 12, 2018, 08:53:11 am »
Looking for info about how to send/receive files using indy 10, i found this article:

https://stackoverflow.com/questions/16871393/need-help-sending-file-with-indy

It is to old so im trying to update the info.

Server:
Code: Pascal  [Select]
  1. CONST_ArchivoAccData = 'DATA/accsum.dat';
  2. AFileStream := TFileStream.Create(CONST_ArchivoAccData, fmOpenRead + fmShareDenyNone);
  3.       try
  4.       Conexiones[Slot].context.Connection.IOHandler.WriteLn('FILEACCSUM');
  5.       Conexiones[Slot].context.connection.IOHandler.Write(AFileStream);
  6.       OutputText('File AccSum sended');
  7.       finally
  8.       AFileStream.Free;
  9.       end;  

I can see the text 'File sended' and the server runs normally after that.

Client:
Code: Pascal  [Select]
  1. LLine := ConexionesCliente[Number].IOHandler.ReadLn(IndyTextEncoding_UTF8);
  2.    if LLine = 'FILEACCSUM' then
  3.       begin
  4.       if FileExists(CONST_ArchivoAccData) then DeleteFile(CONST_ArchivoAccData);
  5.       AFileStream := TFileStream.Create(CONST_ArchivoAccData, fmCreate);
  6.       ConexionesCliente[Number].IOHandler.ReadStream(AFileStream);
  7.       AFileStream.Free;

The cliente freezes, the file is created as expected, but with 19.146 Kb of size (expected 1 kb) What im missing? Thank you

« Last Edit: July 13, 2018, 07:00:35 pm by torbente »

torbente

  • Full Member
  • ***
  • Posts: 205
Re: File exchange using indy.
« Reply #1 on: July 13, 2018, 07:00:14 pm »
I finally found the way, just editing this line:

Code: Pascal  [Select]
  1. Conexiones[Slot].context.connection.IOHandler.Write(AFileStream,0,true);

Remy Lebeau

  • Sr. Member
  • ****
  • Posts: 426
    • Lebeau Software
Re: [SOLVED] File exchange using indy.
« Reply #2 on: July 13, 2018, 10:47:51 pm »
Looking for info about how to send/receive files using indy 10, i found this article:

https://stackoverflow.com/questions/16871393/need-help-sending-file-with-indy

It is to old

Yes, that post was written for Indy 9, not Indy 10.

Code: Pascal  [Select]
  1. Conexiones[Slot].context.connection.IOHandler.Write(AFileStream);
  2. ...
  3. ConexionesCliente[Number].IOHandler.ReadStream(AFileStream);

You have a mismatch here.  You are using the correct methods, but with the wrong parameters.  By default, TIdIOHandler.Write(TStream) DOES NOT send the stream size, but TIdIOHandler.ReadStream() DOES expect a size to be sent.  This is one of the rare cases where a pair of write/read methods do not compliment each other.

You need to either:

1. set the AWriteByteCount parameter of Write() to True:

 
Code: Pascal  [Select]
  1.  Conexiones[Slot].Context.Connection.IOHandler.LargeStream := True;
  2.  Conexiones[Slot].Context.Connection.IOHandler.Write(AFileStream, 0, True);
  3.  ...
  4.  ConexionesCliente[Number].IOHandler.LargeStream := True;
  5.  ConexionesCliente[Number].IOHandler.ReadStream(AFileStream);

 LargeStream controls whether the stream size is sent/read as a 32bit or 64bit integer.

2. send/read the stream size explicitly:

 
Code: Pascal  [Select]
  1.  Conexiones[Slot].Context.Connection.IOHandler.Write(AFileStream.Size);
  2.  Conexiones[Slot].Context.Connection.IOHandler.Write(AFileStream);
  3.  ...
  4.  ConexionesCliente[Number].IOHandler.LargeStream := True;
  5.  ConexionesCliente[Number].IOHandler.ReadStream(AFileStream);

 Or:

 
Code: Pascal  [Select]
  1.  Conexiones[Slot].Context.Connection.IOHandler.WriteLn(IntToStr(AFileStream.Size));
  2.  Conexiones[Slot].Context.Connection.IOHandler.Write(AFileStream);
  3.  ...
  4.  Size := StrToInt64(ConexionesCliente[Number].IOHandler.ReadLn);
  5.  ConexionesCliente[Number].IOHandler.ReadStream(AFileStream, Size, False);

 Or, however other way you want to send/read the stream size.
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

 

Recent

Get Lazarus at SourceForge.net. Fast, secure and Free Open Source software downloads Open Hub project report for Lazarus