How to convert a record from host to network byte order (big endian)?

99封情书 提交于 2019-11-28 10:39:11

问题


I have a record:

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

which I need send to server using UDP protocol

I fill it

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

and sending it

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

or maybe I'm doing something wrong? I need to send "bign endian" packet

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

Thanks.


回答1:


Assuming your code is running in a little-endian OS/Machine (like Windows/Intel), you can just reverse the individual bytes of your packet, for example, include the FMX.Types unit in your uses clause:

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;



回答2:


What you are actually doing is converting from host byte order to network byte order. All standard sockets libraries provide helper functions to do that.

For example, Winsock offers htons, htonl etc. And in the opposite direction you have ntohs, ntohl etc. If you are using Indy, then the equivalent functions are GStack.HostToNetwork and GStack.NetworkToHost.

You should serialize each field into a byte stream, with each field being transformed by the appropriate hton* function. Then you can put the byte stream on the wire.



来源:https://stackoverflow.com/questions/13505211/how-to-convert-a-record-from-host-to-network-byte-order-big-endian

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!