• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 325
  • Last Modified:

Trouble sending file over 100mb with Indy Sockets

Hi people,

I'm having trouble when I tried to send one file with size over 100 mb with Indy TCP Sockets.

The code used are this:

Client:

  vSize := tcpClient.ReadInteger;
  if vSize > 0 then
  begin
    vFile:= 'c:\test_file.xyz';
    fStream := TFileStream.Create( vFile, fmCreate );
    try
      while tcpClient.Connected do
        tcpClient.ReadStream( fStream, -1, True );
      //tcpClient.ReadStream( fStream, vSize, False ); //same problem occur
    finally
      FreeAndNil(Stream1);
    end;
  end;

Server:

  vFile := 'c:\file_over_100mb.xyz';
  if FileExists( vFile ) then
  begin
    fStream := TFileStream.Create( vFile, fmOpenRead or fmShareDenyNone );
    try
      AThread.Connection.WriteInteger( fStream.Size, False );
      AThread.Connection.OpenWriteBuffer;
      AThread.Connection.WriteStream( fStream, True, False, fStream.Size );
      AThread.Connection.CloseWriteBuffer;
      AThread.Connection.Disconnect;
    finally
      fStream.Free;
    end;
  end
  else
    AThread.Connection.WriteInteger( 0, False );


This code works fine with files of 5, 10 or 20 mb....

Thanks...
0
alijunior
Asked:
alijunior
1 Solution
 
2266180Commented:
hm... I tried the code with a small file and it's not working properly (delphi 7, indy 9) meaning that the integer is not sent through correctly because you do:

 AThread.Connection.WriteInteger( fStream.Size, False );
and then
 vSize := tcpClient.ReadInteger; (defaults to true) ;)

next thing will probably bne that 100 mb = 100 * 1024*1024 cannot be represented on an integer,, can it now :)

so I suggest using writln and readln and converting from and to int64.

but still you have the issue of overloading your memory. I did a test and the memory of my app went way up, also almost freezing my pc.

so what I suggest is uding a packet based protocol which you define and sending small chunks. an easy example would be (some pseudocode):

while file available do
begin
  size=readblock(file,buffer,buffersize);
  writecardinal(size);
  writebuffer(buffer);
end;

cheers
0
 
alijuniorAuthor Commented:
Hi ciuly...

I solve that as follows:

procedure v480_tcpSendFile( tcpConnection : TIdTCPServerConnection; vStream : TStream; cChunk : Integer = 1024 );
var mStream : TMemoryStream;
    vChunk,
    vSize : Integer;
begin

  vSize := vStream.Size;
  tcpConnection.WriteInteger( vSize );

  if vSize > 0 then
  begin
    tcpConnection.WriteInteger( cChunk );
    vStream.Seek( 0, soBeginning );
    mStream := TMemoryStream.Create;
    try
      repeat

        if vSize - vStream.Position >= cChunk then
          vChunk := cChunk
        else
          vChunk := vSize - vStream.Position;

        mStream.Clear;
        mStream.CopyFrom( vStream, vChunk );
        mStream.Seek( 0, soBeginning );

        tcpConnection.OpenWriteBuffer;
        tcpConnection.WriteStream( mStream, True, False, mStream.Size );
        tcpConnection.CloseWriteBuffer;

      until vStream.Position = vSize;

    finally
      mStream.Free;
    end;
  end;

end;

procedure v480_tcpRecvFile( tcpClient : TIdTCPClient; vStream : TStream );
var mStream : TMemoryStream;
    vSize : Integer;
    vChunk : Integer;
begin

  vSize := tcpClient.ReadInteger;
  if vSize > 0 then
  begin
    vChunk := tcpClient.ReadInteger;
    mStream := TMemoryStream.Create;
    try
      repeat
        mStream.Clear;
        tcpClient.ReadStream( mStream, vChunk, False );
        mStream.Seek( 0, soBeginning );
        vStream.CopyFrom( mStream, mStream.Size );

        if vSize - vStream.Position < vChunk then
          vChunk := vSize - vStream.Position;

      until vStream.Size >= vSize;
    finally
      mStream.Free;
    end;
  end;

end;
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Tackle projects and never again get stuck behind a technical roadblock.
Join Now