-3

我正在寻找一种最快(股票市场应用程序,对时间要求极高)的解决方案,用于将大量加密的 RawByteString 数据(高达 500 条记录/秒)从TIdTCPServer 传输TIdTCPClient

最好的方法是什么?

提前致谢!

编辑:

在我的项目中,我需要使用 n'Software 库来加密字符串。最快的加密方法返回一个 RawByteString。从理论上讲,我应该只为加密字符串设置 CodePage 并将其传输为 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;
4

1 回答 1

0

传输加密RawByteString为 UTF-8 字符串的二进制文件是完全错误的,无论速度有多快。使用 Indy 10 传输二进制数据的最佳方式是使用TIdBytesorTStream代替。两者IOHandler都有读/写方法,例如:

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;
于 2017-04-11T15:53:03.630 回答