Reputation: 1195
We know that there are two types of Endianness - big-endian (BE) and little-endian (LE). So typically we have LE at application layer, so-called "host byte order".
Usually in application we translate host byte order (LE) port of transport protocol to network byte order (BE) such way:
struct sockaddr_in sockaddr = {0};
// ...
sockaddr.sin_port = htons(60592);
Practically all network protocols use BE bytes representation.
In this example 60592
in host byte order will be ECB0
as says my calculator. So I thought that it should be swapped inside transport header to B0EC
, but it doesn't. Where am I wrong?
Upvotes: 1
Views: 738
Reputation: 17403
60592 is 0xECB0 in hexadecimal. As a 16-bit, unsigned value broken into two 8-bit bytes, the value of the least significant byte is 0xB0 and the value of the most significant byte is 0xEC. A machine using little endian byte order will store the value in memory least significant byte first, so it will be stored as the sequence 0xB0, 0xEC. If those two bytes are copied into the network packet using memcpy()
, the bytes will appear in the packet in the same order 0xB0, 0xEC. However, the network protocol represents 16-bit values in big endian byte order, so the byte sequence 0xB0, 0xEC represents the 16-bit, unsigned value 0xB0EC or 45292.
On a machine using little endian byte order, htons(60592)
will produce the value 45292 or 0xB0EC. That will be stored in memory as the byte sequence 0xEC, 0xB0. When copied into the network packet using memcpy()
, the bytes will appear in the packet in the same order 0xEC, 0xB0. In the network protocol using big endian byte order, the byte sequence 0xEC, 0xB0 represents the 16-bit, unsigned value 0xECB0 or 60592 as required.
Upvotes: 1