[SDL_net] Endianness

Hi, do I have to consider byte orders while working with TCPsocket in case of SDLNet_TCP_Recv and SDLNet_TCP_Send. If yes: what’s the way to handle endianness in this case?

Kind regards
Glocke

You should pack(when sending)\unpack(when recving) all your integers in any of endianness (by your choice). For example(pseudo code):

uint32_t GetBe32(const uint8_t *data)
{
    uint32_t val;
    val =  GetBe16(data) << 16;
    val |= GetBe16(&data[2]);
    return val;
}

void PutBe32(uint8_t* data,uint32_t val)
{
      data[0] = val >> 24;
      data[1] = val >> 16;
      data[2] = val >> 8;
      data[3] = val;
}


// When you send:
uint32_t value = 123456;

PutBe32(data,value);
SDLNet_TCP_Send(sock,data,size);


// When you recv:
uint32_t value;

size = SDLNet_TCP_Recv(sock, data, maxlen);
if (size > 4)
    value = GetBe32(data);
else
    goto error;

20.03.2013, ? 17:07, Glocke ???(?):> Hi, do I have to consider byte orders while working with TCPsocket in case of SDLNet_TCP_Recv and SDLNet_TCP_Send. If yes: what’s the way to handle endianness in this case?

Kind regards
Glocke


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Yes, SDL_net has no knowledge of the endianness of the buffers you send and receive.

Fortunately, SDL provides some excellent, optimal functions for reversing the order of bytes in SDL_endian.h

As a general rule, you have three options for transmission (either file or network) endianness:

  1. Assume most machines using the transmitted data will be little-endian (a good general rule now that everyone is using x86)
  2. Convert to network byte order, which is big-endian.
  3. (Less practical): Have the client tell you its endianness, and convert to to client endianness before sending and to native endianness after receiving.

A couple other good rules:

  1. Always transmit text as UTF-8 (if some requirement forces you to use UTF-16 or UTF-32; make sure the byte-order-mark U+FEFF is the first codepoint sent), unless you have no use of characters outside the ASCII range, and in that case transmit as ASCII.
  2. Always transmit the length (in bytes or Unicode code units [what C and C++ call “characters”]) of the text before the text itself.
  3. Always transmit as little data as possible (client bandwidth is often limited by their ISP, and server bandwidth isn’t exactly free).
  4. Never transmit floating point numbers. Convert them either to fixed precision (if the only acceptable range is between 0 and 1 or -1 and 1) or a ratio. I know SDL provides a function for byte-swapping floats, but that doesn’t make it a good idea, and conversion is rather simple. And, fun fact, a 64-bit ratio can represent PI and e (Euler’s number) as accurately (to the 15th decimal place) as a 64-bit double can.------------------------
    Nate Fries