Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 如何将接收到的数据解包到";“大端词”;记录在案?_Delphi_Delphi Xe3 - Fatal编程技术网

Delphi 如何将接收到的数据解包到";“大端词”;记录在案?

Delphi 如何将接收到的数据解包到";“大端词”;记录在案?,delphi,delphi-xe3,Delphi,Delphi Xe3,我有记录 type Treply = record c: integer; b: integer; a: int64; end; 我使用UDP协议从服务器接收数据,数据是“big-endian” 如何将接收到的_数据解码为正常的int/int/int64并将其放入记录三层 在本例中,由于记录没有填充,因此只需将缓冲区的内容复制到记录上即可 var Reply: TReply; .... Move(received_data[0], Reply, SizeOf

我有记录

type
  Treply = record
    c: integer;
    b: integer;
    a: int64;
  end;
我使用UDP协议从服务器接收数据,数据是“big-endian”

如何将接收到的_数据解码为正常的int/int/int64并将其放入记录三层


在本例中,由于记录没有填充,因此只需将缓冲区的内容复制到记录上即可

var
  Reply: TReply;
....
Move(received_data[0], Reply, SizeOf(Reply));
然后需要从网络字节顺序转换为主机字节顺序。从你之前的问题中你知道怎么做

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

TReply = packed record
  ....
在调用
Move
之前,您还应该检查
received\u data
是否包含正确数量的信息

就个人而言,我可能会将您的记录构建成更强大的功能,利用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;
如果长度(收到的数据)大小为(回复),则
引发一些异常。创建(“…”);
移动(收到_数据[0],回复,SizeOf(回复));
Reply:=Reply.NetworkToHost;

如果在小型endian机器上执行,效果相同。但从逻辑上讲,这不是一回事。在我看来,这是你想要的。您不需要
反向字节
。您想要
NetworkToHost
,或者在上一个问题中是
HostToNetwork
。尽管它们在小型endian机器上的效果相同,但使用
NetworkToHost
/
HostToNetwork
将使代码更具可读性和清晰性。我不明白你为什么需要从FireMonkey引入反向字节。你在用印地。因此,请使用Indy本机工具进行主机/网络字节顺序。好的,谢谢,以及如何使用主机网络而不是反向字节(@BEPacket.a,SizeOf(BEPacket.a))?我在尝试这样做时出错:=packet.HostToNetwork;当packet.a:=123时,我得到了“访问可用性错误..”;包b:=55;包c:=321;packet:=packet.HostToNetwork;indy bug?这是因为您尚未创建任何indy组件,因此未创建
GStack
。您需要调用TIdStack.IncUsage,以便创建
GStack
。当您创建Indy组件时会发生这种情况。如果您在任何地方都不这样做,那么您需要在某个地方调用TIdStack.IncUsage。例如,在初始化部分中。然后在完成后调用
TIdStack.decussion
。像这样吗?初始化TIdStack.IncUsage;完成TIdStack.decussion;现在一切都好了,谢谢)@Remy有什么推荐的方法可以确保GStack已经创建?
if Length(received_data)<>SizeOf(Reply) then
  raise SomeException.Create('...');
Move(received_data[0], Reply, SizeOf(Reply));
Reply := Reply.NetworkToHost;