如何以“大端”解压缩接收到的数据。记录下来? [英] How to unpack received data in "big endian" into record?
问题描述
我有一条记录
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屋!