1

我有记录

type
  Treply = record
    c: integer;
    b: integer;
    a: int64;
  end;

我使用 UDP 协议从服务器接收数据,数据是“大端”

udp : TIdUDPClient;
received_data : TIdBytes;

udp.ReceiveBuffer(received_data);

如何将 received_data 解码为正常的 int/int/int64 并将其放入记录 Treply ?

谢谢

4

1 回答 1

2

在这种情况下,由于记录没有填充,您可以简单地将缓冲区的内容复制到您的记录中。

var
  Reply: TReply;
....
Move(received_data[0], Reply, SizeOf(Reply));

然后您需要从网络字节顺序转换为主机字节顺序。而且您从上一个问题中知道如何做到这一点。

为确保您永远不会被记录填充/对齐问题所困扰,建议您打包任何传输到网络上的记录:

TReply = packed record
  ....

received_data您还应该在调用之前检查包含正确数量的信息Move

就个人而言,我可能会将您的记录构建成更强大的东西,利用 Indy 的功能在主机和网络字节顺序之间进行转换。

type
  TReply = packed record
    c: integer;
    b: integer;
    a: int64;
    function HostToNetwork: TReply;
    function NetworkToHost: TReply;
  end;

function TReply.HostToNetwork: TReply;
begin
  Result.c := GStack.HostToNetwork(Cardinal(c));
  Result.b := GStack.HostToNetwork(Cardinal(b));      
  Result.a := GStack.HostToNetwork(a);
end;

function TReply.NetworkToHost: TReply;
begin
  Result.c := GStack.NetworkToHost(Cardinal(c));
  Result.b := GStack.NetworkToHost(Cardinal(b));      
  Result.a := GStack.NetworkToHost(a);
end;

将它们放在一起,您的反序列化代码如下所示:

if Length(received_data)<>SizeOf(Reply) then
  raise SomeException.Create('...');
Move(received_data[0], Reply, SizeOf(Reply));
Reply := Reply.NetworkToHost;
于 2012-11-22T20:49:50.183 回答