delphi - Indy,如何知道所需缓冲区的大小?

标签 delphi buffer indy

我在使用Indy(idTCPServer组件)读取客户端发送的数据时遇到一些问题,数据本身是十六进制格式的,所以我不能使用AThread.Connection.ReadLn( );为此...

这是我的客户端发送的示例数据

24 24 00 11 12 34 56 FF FF FF FF 50 00 8B 9B 0D 0A

24 24 00 13 12 34 56 FF FF FF FF 90 02 00 0A 8F D4 0D 0A

PS:它以十六进制字节为单位(数据长度可能因命令而异,最大160字节),由于 $00 转换为 null,因此我无法获取字符串表示形式(这意味着我无法使用 ReadLn)

这是我的示例代码

procedure TfrmMain.IdTCPServerExecute(AThread: TIdPeerThread);
var
  Msg : Array[0..255] of Byte;
begin      
  AThread.connection.ReadBuffer(Msg,SizeOf(Msg));
  AThread.connection.WriteBuffer(Msg,MsgSize,true);
end;

如果客户端不发送 255 字节数据,此代码将不起作用,而在我的情况下,数据长度可能会有所不同,我已经尝试过,但没有输出响应

procedure TfrmMain.IdTCPServerExecute(AThread: TIdPeerThread);
var
  Msg : Array of Byte;
  MsgSize : integer;
begin  
  MsgSize := AThread.connection.ReadInteger; //doesn't actually get packet length?
  SetLength(Msg, MsgSize);    
  AThread.connection.ReadBuffer(Msg,MsgSize);
  AThread.connection.WriteBuffer(Msg,MsgSize,true);
end;

那么我到底如何计算客户端发送的数据字节数(数据包长度)?或者有人可以告诉我读取数据的正确代码吗?

最佳答案

简单的答案是:你不能。 TCP 是一个协议(protocol),因此没有消息的概念。数据以 block 的形式接收,其大小可能(并且将会)与实际发送的缓冲区不同(网络堆栈可以随意切片或合并流)。
您可以在 TCP 之上构建消息协议(protocol),例如通过“大小字段”开始传输以及每个后续消息,然后仅等待所需的字节;您仍然需要检查收到的实际尺寸并重新阅读其余部分(如果适用)。

要点是:TCP 世界中的数据包长度与发送消息的长度无关
TIdTCPConnection 在所有 Read 方法背后所做的是:
从网络堆栈读取所有可用数据,将其附加到内部输入缓冲区,并从缓冲区开头返回请求的N个字节(如果可用)(等待下一个 block ) ,如果没有)。

关于delphi - Indy,如何知道所需缓冲区的大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5189618/

相关文章:

delphi - 是否可以声明一个包含另一个常量数组的常量数组?

delphi - 使用 Inno Setup 中格式化(部分粗体)的文本制作安装程序?

javascript - 在 IPFS 中上传数组

delphi - 是否可以在Delphi XE和DataSnap中使用Indy 10.5.8.0?

delphi - 印地 9 和印地 10 有什么区别?

Delphi:TIdHTTP 与 TNetHTTPClient

Delphi Firedac 内存表

delphi - 如何禁用 Delphi 作为即时调试器?

Emacs:如何默认切换 Buffer-menu-files-only

Apache SSL 设置最大片段长度