Link to home
Start Free TrialLog in
Avatar of alijunior
alijunior

asked on

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...
ASKER CERTIFIED SOLUTION
Avatar of 2266180
2266180
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of alijunior
alijunior

ASKER

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;