1
votes

I need to transfer many files from one tcp indy server to a client using INDY10 components. Is there a way to improve the transfer speed by setting any parameter for the TCP client or server communication.

File Size : ~ 10 MBYte .... 50 Mybte

Is there a limit in respect to file size , my PC is using WIN 7 x64 and 32 GBYTE RAM Our network is LAN.100 other location LAN already improved to GIGABIT LAN

  function SendStream(AContext: TIdContext; AStream: TStream): Boolean; overload;
  var
    StreamSize: LongInt;
  begin
    try
      Result := True;
      try
        StreamSize := (AStream.Size);

        // AStream.Seek(0, soFromBeginning);

        AContext.Connection.IOHandler.Write(LongInt(StreamSize));
        AContext.Connection.IOHandler.WriteBufferOpen;
        AContext.Connection.IOHandler.Write(AStream, 0, False);
        AContext.Connection.IOHandler.WriteBufferFlush;
      finally
        AContext.Connection.IOHandler.WriteBufferClose;
      end;
    except
      Result := False;
    end;
  end;
2
You've posted absolutely no code or useful information we can use to try and help you. It doesn't matter that you're using Win7 64, or what size file you've got; without code, we can't tell you if you're doing something wrong or what you can do to make it better, as we have no idea what you're doing now. Also, you don't need to put tag information in your title - the tag system works very well here, and doesn't need any help. :-) - Ken White
Or what speed you get now. It might already be at the max, given TCP/IP overhead. - Marco van de Voort
Show the code and actual numbers to set a baseline. - jachguate
Nice edit, but, you still doesn't tell us what your current transfer speed is? - jachguate
IMHO The only speed improvement you can achieve is actually sending less bytes over the wire by the means of compression (if the source file is compressible offcourse) - whosrdaddy

2 Answers

2
votes

The sending code can be reduced to

  function SendStream(AContext: TIdContext; AStream: TStream): Boolean;
  begin
    Result := True;
    try
      AContext.Connection.IOHandler.Write(AStream, 0, True);
    except
      Result := False;
    end;
  end;

The third parameter causes Indy to write the stream size as an Integer or Int64 (depending on the value of the TIdIOHandler.LargeStream property) value to the client.

The client then can read the stream size and the stream using

// reads the stream size then reads the stream data
Client.IOHandler.ReadStream(MyStream, -1, False);

(found in Delphi TidTCPServer and TidTCPClient transferring a record where only the transfer direction is reversed)

1
votes

Send the stream directly and save another copy of the bytes being made. Specifically in your example - remove the 3 lines of code mentioning WriteBuffer.

Depending on the size of the stream and the number of concurrent clients, you may be thrashing the heck out of your memory manager by using a large buffered copy that you don't really need. Your goal on big transfers is to limit the number of times something has to process the entire stream.