如何将“big endian”中收到的数据解压缩到记录中?

时间:2012-11-22 20:43:45

标签: delphi delphi-xe3

我有记录

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

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

udp : TIdUDPClient;
received_data : TIdBytes;

udp.ReceiveBuffer(received_data);

如何将received_data解码为普通的int / int / int64并将其放入Treply记录中?

由于

1 个答案:

答案 0 :(得分:1)

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

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;