1

我有一个记录:

  Tconnecting = record
  var
    a: int64;
    b: integer;
    c: integer;
  end;

我需要使用 UDP 协议发送到服务器

我填

  packet.a := StrToInt64('0x1234567890');
  packet.b := 0;
  packet.c := RandomRange(1, 9999999);

并发送

  SetLength(send_data, sizeof(packet));
  send_data := RawToBytes(packet, SizeOf(packet));
  udp.SendBuffer(make_it_big_endian(send_data)); <-- the question... "network byte order"

或者我做错了什么?我需要发送“大端”数据包

pack("N*", int64, int, int); (this is in PHP)

谢谢。

4

2 回答 2

4

您实际上正在做的是将主机字节顺序转换为网络字节顺序。所有标准套接字库都提供了帮助函数来做到这一点。

例如,Winsock 提供 htons、htonl 等。相反,您有 ntohs、ntohl 等。如果您使用的是 Indy,那么等效的函数是GStack.HostToNetworkand GStack.NetworkToHost

您应该将每个字段序列化为字节流,每个字段都由适当的 hton* 函数转换。然后你可以把字节流放在线上。

于 2012-11-22T07:02:36.877 回答
1

假设您的代码在 little-endian OS/Machine(如 Windows/Intel)中运行,您可以反转数据包的各个字节,例如,在您的 uses 子句中包含 FMX.Types 单元:

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

procedure TForm1.Button1Click(Sender: TObject);
var
  Packet, BEPacket: Tconnecting;
begin
  packet.a := $0102030405060708;
  packet.b := $01020304;
  packet.c := $05060708;
  //big endian packet  
  BEPacket := Packet;

  ReverseBytes(@BEPacket.a, SizeOf(BePacket.a));
  ReverseBytes(@BEPacket.b, SizeOf(BePacket.b));
  ReverseBytes(@BEPacket.c, SizeOf(BePacket.c));

  Memo1.Lines.Add(Format('a: %16.16x => %16.16x', [Packet.a, BEPacket.a]));
  Memo1.Lines.Add(Format('b: %8.8x => %8.8x', [Packet.b, BEPacket.b]));
  Memo1.Lines.Add(Format('c: %8.8x => %8.8x', [Packet.c, BEPacket.c]));
end;
于 2012-11-22T06:33:02.107 回答