gpt4 book ai didi

delphi - Indy 写缓冲/高效 TCP 通信

转载 作者:可可西里 更新时间:2023-11-01 02:30:49 27 4
gpt4 key购买 nike

我知道,我问了很多问题......但作为一名新的 delphi 开发人员,我一直在思考所有这些问题:)

这个使用 indy 10 处理 TCP 通信。为了提高通信效率,我将客户端操作请求编码为单个字节(在大多数情况下,当然后面跟着其他数据字节,但在这种情况下只有一个字节)。问题是

var Bytes : TBytes;
...
SetLength (Bytes, 1);
Bytes [0] := OpCode;
FConnection.IOHandler.Write (Bytes, 1);
ErrorCode := Connection.IOHandler.ReadByte;

不会立即发送该字节(至少不会调用服务器执行处理程序)。例如,如果我将“1”更改为“9”,一切正常。我假设 Indy 缓冲传出字节并尝试使用

禁用写缓冲
FConnection.IOHandler.WriteBufferClose;

但这并没有帮助。如何发送单个字节并确保立即发送?并且 - 我在这里添加另一个小问题 - 使用 indy 发送整数的最佳方式是什么?不幸的是,我在 TIdTCPServer 的 IOHandler 中找不到像 WriteInteger 这样的函数......和

WriteLn (IntToStr (SomeIntVal))

对我来说似乎效率不高。无论我连续使用多个写入命令还是将内容打包到一个字节数组中并发送一次,这会有什么不同吗?

感谢您的回答!

编辑:我添加了一个提示,表明我正在使用 Indy 10,因为读写过程似乎发生了重大变化。

最佳答案

写缓冲默认是禁用的。您可以通过测试 fConnection.IOHandler.WriteBufferingActive 属性来检查写入缓冲以查看它在您的代码中是否处于事件状态。

就发送整数的最佳方式而言……“这取决于”您的协议(protocol)和总体目标。具体来说,使用 FConnection.IOHandler.Write() 因为有重载方法可以写入任何类型的数据,包括整数。

取自 IdIOHandler:

// Optimal Extra Methods
//
// These methods are based on the core methods. While they can be
// overridden, they are so simple that it is rare a more optimal method can
// be implemented. Because of this they are not overrideable.
//
//
// Write Methods
//
// Only the ones that have a hope of being better optimized in descendants
// have been marked virtual
procedure Write(const AOut: string; const AEncoding: TIdEncoding = enDefault); overload; virtual;
procedure WriteLn(const AEncoding: TIdEncoding = enDefault); overload;
procedure WriteLn(const AOut: string; const AEncoding: TIdEncoding = enDefault); overload; virtual;
procedure WriteLnRFC(const AOut: string = ''; const AEncoding: TIdEncoding = enDefault); virtual;
procedure Write(AValue: TStrings; AWriteLinesCount: Boolean = False; const AEncoding: TIdEncoding = enDefault); overload; virtual;
procedure Write(AValue: Byte); overload;
procedure Write(AValue: Char; const AEncoding: TIdEncoding = enDefault); overload;
procedure Write(AValue: LongWord; AConvert: Boolean = True); overload;
procedure Write(AValue: LongInt; AConvert: Boolean = True); overload;
procedure Write(AValue: SmallInt; AConvert: Boolean = True); overload;
procedure Write(AValue: Int64; AConvert: Boolean = True); overload;
procedure Write(AStream: TStream; ASize: Int64 = 0; AWriteByteCount: Boolean = False); overload; virtual;

您遇到的另一个问题是“连续使用多个写入命令或将内容打包到一个字节数组中并发送一次是否有区别?”对于大多数情况,是的,它有所作为。对于压力很大的服务器,您将不得不更多地参与如何来回发送字节,但是在这个级别上,您应该将发送抽象为一个单独的协议(protocol)类型类,该类构建要发送的数据并以burst 并有一个接收协议(protocol),接收一堆数据并将其作为一个完整的单元处理,而不是将事情分解为发送/接收整数、字符、字节数组等。

作为一个非常粗略的快速示例:

TmyCommand = class(TmyProtocol)
private
fCommand:Integer;
fParameter:String;
fDestinationID:String;
fSourceID:String;
fWhatever:Integer;
public
property Command:Integer read fCommand write fCommand;
...

function Serialize;
procedure Deserialize(Packet:String);
end;

function TmyCommand.Serialize:String;
begin
//you'll need to delimit these to break them apart on the other side
result := AddItem(Command) +
AddItem(Parameter) +
AddItem(DestinationID) +
AddItem(SourceID) +
AddItem(Whatever);
end;
procedure TMyCommand.Deserialize(Packet:String);
begin
Command := StrToInt(StripOutItem(Packet));
Parameter := StripOutItem(Packet);
DesintationID := StripOutItem(Packet);
SourceID := StripOutItem(Packet);
Whatever := StrToInt(StripOutItem(Packet));
end;

然后通过以下方式发送:

  FConnection.IOHandler.Write(myCommand.Serialize());

另一方面,您可以通过 Indy 接收数据,然后

  myCommand.Deserialize(ReceivedData);

关于delphi - Indy 写缓冲/高效 TCP 通信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/605580/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com