I'm looking for a most fastest (stock market application, extremely time critical) solution for transfer a lot of encrypted RawByteString-data (up to 500 records/s, ) from TIdTCPServer to TIdTCPClient.
What is the best way to do that?
Thanks in advance!
Edit:
In my project I need to use a n'Software library for the encryption of strings. The fastest encryption method returns a RawByteString. Theoretically, I should only set the CodePage for encrypted string and transfer it UTF8 encoded, but all my attempts failed.
So seemed to me the most logical:
Server:
var
rbs: RawByteString;
begin
rbs := EncryptString(AInput, DEFAULT_ENCRYPTION_KEY);
SetCodePage(rbs, 65001, true);
AContext.Connection.IOHandler.WriteLn(rbs, IndyTextEncoding_UTF8);
...
end;
Client:
var
rbs: string;
Output: string;
begin
rbs := IdTCPClient1.IOHandler.ReadLn(IndyTextEncoding_UTF8);
Output := DecryptString(rbs, DEFAULT_ENCRYPTION_KEY);
...
end;
Transferring a binary encrypted RawByteString
as a UTF-8 string is just plain wrong, no matter how fast it may be. The best way to transfer binary data with Indy 10 is to use a TIdBytes
or TStream
instead. The IOHandler
has reading/writing methods for both, for example:
var
rbs: RawByteString;
begin
rbs := EncryptString(AInput, DEFAULT_ENCRYPTION_KEY);
AContext.Connection.IOHandler.Write(Int32(Length(rbs)));
AContext.Connection.IOHandler.Write(RawToBytes(PAnsiChar(rbs)^, Length(rbs)));
...
end;
var
buf: TIdBytes;
rbs: RawByteString;
Output: string;
begin
IdTCPClient1.IOHandler.ReadBytes(buf, IdTCPClient1.IOHandler.ReadInt32);
SetLength(rbs, Length(buf));
BytesToRaw(buf, PAnsiChar(rbs)^, Length(rbs));
Output := DecryptString(rbs, DEFAULT_ENCRYPTION_KEY);
...
end;
Alternatively:
var
rbs: RawByteString;
strm: TIdMemoryBufferStream;
begin
rbs := EncryptString(AInput, DEFAULT_ENCRYPTION_KEY);
strm := TIdMemoryBufferStream.Create(PAnsiChar(rbs), Length(rbs));
try
AContext.Connection.IOHandler.LargeStream := False;
AContext.Connection.IOHandler.Write(strm, 0, True);
finally
strm.Free;
end;
...
end;
var
strm: TMemoryStream;
rbs: RawByteString;
Output: string;
begin
strm := TMemoryStream.Create;
try
IdTCPClient1.IOHandler.LargeStream := False;
IdTCPClient1.IOHandler.ReadStream(strm, -1, False);
SetLength(rbs, strm.Size);
Move(strm.Memory^, PAnsiChar(rbs)^, Length(rbs));
finally
strm.Free;
end;
{ alternatively:
SetLength(rbs, IdTCPClient1.IOHandler.ReadInt32);
strm := TIdMemoryBufferStream.Create(PAnsiChar(rbs), Length(rbs));
try
IdTCPClient1.IOHandler.ReadStream(strm, Length(rbs), False);
finally
strm.Free;
end;
}
Output := DecryptString(rbs, DEFAULT_ENCRYPTION_KEY);
...
end;