jpf*_*ius 8 delphi performance tcp client-server indy
我知道,我问了很多问题......但是作为一个新的delphi开发人员,我一直在讨论所有这些问题:)
使用印10.为了使通信效率这一个与TCP通信交易,我编写一个客户端操作请求作为单个字节(在大多数情况下,接着,当然其他数据字节,但在这种情况下,只有一个单一的字节).问题是
var Bytes : TBytes;
...
SetLength (Bytes, 1);
Bytes [0] := OpCode;
FConnection.IOHandler.Write (Bytes, 1);
ErrorCode := Connection.IOHandler.ReadByte;
Run Code Online (Sandbox Code Playgroud)
不立即发送该字节(至少不调用服务器执行处理程序).如果我将'1'更改为'9',例如一切正常.我假设Indy缓冲了输出字节,并尝试禁用写缓冲
FConnection.IOHandler.WriteBufferClose;
Run Code Online (Sandbox Code Playgroud)
但它没有帮助.如何发送单个字节并确保立即发送?并且 - 我在这里添加另一个小问题 - 使用indy发送整数的最佳方法是什么?不幸的是,我无法在TIdTCPServer的IOHandler中找到像WriteInteger这样的函数......而且
WriteLn (IntToStr (SomeIntVal))
Run Code Online (Sandbox Code Playgroud)
对我来说似乎不是很有效率.是否有所作为我是否使用多个写命令行或字节数组一起收拾东西,并发送一次?
谢谢你的回答!
编辑:我补充说,我使用的是印地10日以来似乎有关于读了重大变化,写程序的提示.
默认情况下禁用写缓冲.您可以通过测试fConnection.IOHandler.WriteBufferingActive属性来检查写缓冲以查看它是否在您的代码中处于活动状态.
至于发送整数的最佳方式......"这取决于你的协议和总体目标.具体来说,使用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;
Run Code Online (Sandbox Code Playgroud)
你遇到的另一个问题是"我是否连续使用多个写命令或者在一个字节数组中将所有内容打包在一起并发送一次会有所不同吗?" 对于大多数情况,是的,它会产生影响.对于高度紧张的服务器,您将不得不更多地参与如何来回发送字节,但在此级别,您应该将您的发送抽象为一个单独的协议类型类,该类构建要发送的数据并将其发送到突发并有一个接收协议,接收一堆数据并将其作为一个完整的单元处理,而不是分解为发送/接收整数,字符,字节数组等.
作为一个非常粗略的快速示例:
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;
Run Code Online (Sandbox Code Playgroud)
然后发送此通过:
FConnection.IOHandler.Write(myCommand.Serialize());
Run Code Online (Sandbox Code Playgroud)
另一方面,您可以通过Indy接收数据
myCommand.Deserialize(ReceivedData);
Run Code Online (Sandbox Code Playgroud)