[ACCEPTED]-Byte order with a large array of characters in C-endianness

Accepted answer
Score: 12

Ok, there seems to be problems with what 47 you are doing on two different levels. Part 46 of the confusion here seems to stem for 45 your use of pointers, what type of objects 44 they point to, and then the interpretation 43 of the encoding of the values in the memory 42 pointed to by the pointer(s).

The encoding 41 of multi-byte entities in memory is what 40 is referred to as endianess. The two common 39 encodings are referred to as Little Endian (LE) and Big Endian (BE). With 38 LE, a 16-bit quantity like a short is encoded 37 least significant byte (LSB) first. Under 36 BE, the most significant byte (MSB) is encoded 35 first.

By convention, network protocols normally 34 encode things into what we call "network 33 byte order" (NBO) which also happens to 32 be the same as BE. If you are sending and 31 receiving memory buffers on big endian platforms, then 30 you will not run into conversion problems. However, your 29 code would then be platform dependent on 28 the BE convention. If you want to write 27 portable code that works correctly on both 26 LE and BE platforms, you should not assume 25 the platform's endianess.

Achieving endian 24 portability is the purpose of routines like 23 ntohs(), ntohl(), htons(), and htonl(). These functions/macros are defined 22 on a given platform to do the necessary 21 conversions at the sending and receiving 20 ends:

  • htons() - Convert short value from host order to network order (for sending)
  • htonl() - Convert long value from host order to network order (for sending)
  • ntohs() - Convert short value from network order to host order (after receive)
  • ntohl() - Convert long value from network order to host order (after receive)

Understand that your comment about 19 accessing the memory when cast back to characters 18 has no affect on the actual order of entities 17 in memory. That is, if you access the buffer 16 as a series of bytes, you will see the bytes 15 in whatever order they were actually encoded 14 into memory as, whether you have a BE or 13 LE machine. So if you are looking at a NBO 12 encoded buffer after receive, the MSB is 11 going to be first - always. If you look 10 at the output buffer after your have converted 9 back to host order, if you have BE machine, the 8 byte order will be unchanged. Conversely, on 7 a LE machine, the bytes will all now be 6 reversed in the converted buffer.

Finally, in 5 your conversion loop, the variable total refers 4 to bytes. However, you are accessing the 3 buffer as shorts. Your loop guard should not be 2 total, but should be:

total / sizeof( unsigned short )

to account for the double 1 byte nature of each short.

Score: 3

This works ok when I'm treating the data 8 as a short, however if I cast the pointer 7 to a char again the bytes are reversed.

That's 6 what I'd expect.

What am I doing wrong?

You 5 have to know what the sender sent: know 4 whether the data is bytes (which don't need 3 reversing), or shorts or longs (which do).

Google 2 for tutorials associated with the ntohs, htons, and 1 htons APIs.

Score: 2

It's not clear what aResponse represents (string 5 of characters? struct?). Endianness is relevant only 4 for numerical values, not chars. You also need 3 to make sure that at the sender's side, all 2 numerical values are converted from host 1 to network byte-order (hton*).

Score: 1

Apart from your original question (which 5 I think was already answered), you should 4 have a look at your malloc statement. malloc allocates 3 bytes and an unsigned short is most likely 2 to be two bytes.

Your statement should look 1 like:

unsigned short *ptr = (unsigned short*) malloc(total * sizeof(unsigned short));
Score: 0

the network byte order is big endian, so 4 you need to convert it to little endian 3 if you want it to make sense, but if it 2 is only an array it shouldn't make a fuss, how 1 does the sender sends it's data ?

Score: 0

For single byte we might not care about 1 byte ordering.

More Related questions