TIdTCPServer/TIdTCPClient: 传输 RawByteString 的最佳方式?
TIdTCPServer/TIdTCPClient: the best way to transfer a RawByteString?
我正在寻找一种最快的(股票市场应用程序,时间极其关键)解决方案,用于从 TIdTCPServer 传输大量加密的 RawByteString 数据(最多 500 records/s, ) 到 TIdTCPClient.
最好的方法是什么?
提前致谢!
编辑:
在我的项目中,我需要使用 n'Software 库来加密字符串。最快的加密方法returns一个RawByteString。理论上,我应该只为加密字符串设置代码页并以UTF8编码传输它,但我的尝试都失败了。
在我看来最合乎逻辑的是:
服务器:
var
rbs: RawByteString;
begin
rbs := EncryptString(AInput, DEFAULT_ENCRYPTION_KEY);
SetCodePage(rbs, 65001, true);
AContext.Connection.IOHandler.WriteLn(rbs, IndyTextEncoding_UTF8);
...
end;
客户:
var
rbs: string;
Output: string;
begin
rbs := IdTCPClient1.IOHandler.ReadLn(IndyTextEncoding_UTF8);
Output := DecryptString(rbs, DEFAULT_ENCRYPTION_KEY);
...
end;
将二进制加密 RawByteString
作为 UTF-8 字符串传输是完全错误的,无论它有多快。使用 Indy 10 传输二进制数据的最佳方式是使用 TIdBytes
或 TStream
代替。 IOHandler
对两者都有 reading/writing 方法,例如:
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;
或者:
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;
我正在寻找一种最快的(股票市场应用程序,时间极其关键)解决方案,用于从 TIdTCPServer 传输大量加密的 RawByteString 数据(最多 500 records/s, ) 到 TIdTCPClient.
最好的方法是什么?
提前致谢!
编辑:
在我的项目中,我需要使用 n'Software 库来加密字符串。最快的加密方法returns一个RawByteString。理论上,我应该只为加密字符串设置代码页并以UTF8编码传输它,但我的尝试都失败了。
在我看来最合乎逻辑的是:
服务器:
var
rbs: RawByteString;
begin
rbs := EncryptString(AInput, DEFAULT_ENCRYPTION_KEY);
SetCodePage(rbs, 65001, true);
AContext.Connection.IOHandler.WriteLn(rbs, IndyTextEncoding_UTF8);
...
end;
客户:
var
rbs: string;
Output: string;
begin
rbs := IdTCPClient1.IOHandler.ReadLn(IndyTextEncoding_UTF8);
Output := DecryptString(rbs, DEFAULT_ENCRYPTION_KEY);
...
end;
将二进制加密 RawByteString
作为 UTF-8 字符串传输是完全错误的,无论它有多快。使用 Indy 10 传输二进制数据的最佳方式是使用 TIdBytes
或 TStream
代替。 IOHandler
对两者都有 reading/writing 方法,例如:
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;
或者:
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;