问题
I have a record
type
Treply = record
c: integer;
b: integer;
a: int64;
end;
I receive data from server using UDP protocol, the data is in "big endian"
udp : TIdUDPClient;
received_data : TIdBytes;
udp.ReceiveBuffer(received_data);
How to decode received_data into normal int/int/int64 and put it into record Treply ?
Thanks
回答1:
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.
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
....
You also ought to check that received_data
contains the right amount of information before calling Move
.
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;
来源:https://stackoverflow.com/questions/13519736/how-to-unpack-received-data-in-big-endian-into-record