如何以“大端”解压缩接收到的数据。记录下来? [英] How to unpack received data in "big endian" into record?

查看:94
本文介绍了如何以“大端”解压缩接收到的数据。记录下来?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一条记录

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

我使用UDP协议从服务器接收数据,数据在大端格式

I receive data from server using UDP protocol, the data is in "big endian"

udp : TIdUDPClient;
received_data : TIdBytes;

udp.ReceiveBuffer(received_data);

如何将接收到的数据解码为普通的int / int / int64并将其放入记录Treply中?

How to decode received_data into normal int/int/int64 and put it into record Treply ?

谢谢

推荐答案

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

In this case, since the record will have no padding, you can simply copy the contents of the buffer onto your record.

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

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

And then you need to convert from network byte order to host byte order. And you know how to do that from your previous question.

为确保您永远不会被记录填充/对齐问题所困扰,建议您将您blit的所有记录打包:

To make sure that you don't ever get caught out by record padding/alignment issues you would be advised to pack any records that you blit onto the wire:

TReply = packed record
  ....

您还应该检查 received_data 是否包含正确数量的信息,然后调用 Move

You also ought to check that received_data contains the right amount of information before calling Move.

我个人可能会将您的记录构建成更强大的功能,从而Indy的函数可以在主机字节序和网络字节序之间进行转换。

Personally I would probably build your record into something a little more powerful, making use of Indy's functions to convert between host and network byte order.

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;

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

Put it all together and your de-serializing code looks like this:

if Length(received_data)<>SizeOf(Reply) then
  raise SomeException.Create('...');
Move(received_data[0], Reply, SizeOf(Reply));
Reply := Reply.NetworkToHost;

这篇关于如何以“大端”解压缩接收到的数据。记录下来?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆