views:

1002

answers:

5

Hey guys, question from a C/Networking newbie...

I'm doing some socket programming in C and trying to wrestle with byte order problems. My request (send) is fine but when I receive data my bytes are all out of order. I start with something like this...

char * aResponse= (char *)malloc(512);
int total = recv(sock, aResponse, 511, 0);

When dealing with this response, each 16bit word seems to have it's bytes reversed (I'm using UDP). I tried to fix that by doing something like this...

    unsigned short * _netOrder= (unsigned short *)aResponse;
    unsigned short * newhostOrder= (unsigned short *)malloc(total);
    for (i = 0; i < total; ++i)
    {
      newhostOrder[i] = ntohs(_netOrder[i]);
    }

This works ok when I'm treating the data as a short, however if I cast the pointer to a char again the bytes are reversed. What am I doing wrong?

Thanks!

A: 

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

CiNN
No, do *not* convert to little endian, convert to the host local order if you want your program to be portable (the OP did not even said what his platform his). That's exactly what ntohs() and ntohl() are for.
bortzmeyer
+3  A: 

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

That's what I'd expect.

What am I doing wrong?

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

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

ChrisW
+2  A: 

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

Zach Scrivena
+1  A: 

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

Your statement should look like:

unsigned short *ptr = (unsigned short*) malloc(total * sizeof(unsigned short));
olli
No, `total` is already measured in bytes, so there's no need to multiply by 2. However, OP should be iterating from 0 to total/2, not from 0 to total.
Adam Rosenfield
Yes you are right. My bad... Late Sunday afternoon :-)
olli
+6  A: 
Tall Jeff