Designate the continent of structure C

I have a structure in C that looks like this:

typedef u_int8_t NN;
typedef u_int8_t X;
typedef int16_t S;
typedef u_int16_t U;
typedef char C;

typedef struct{
 X test;
 NN test2[2];
 C test3[4];
 U test4;
} Test;

I declared the structure and written values ​​for the fields as follows:

Test t;
int t_buflen = sizeof(t);
memset( &t, 0, t_buflen);
t.test = 0xde;
t.test2[0]=0xad; t.test2[1]=0x00;
t.test3[0]=0xbe; t.test3[1]=0xef; t.test3[2]=0x00; t.test3[3]=0xde;
t.test4=0xdeca; 

I am sending this structure via UDP to the server. This is currently fine when I test locally, however now I need to send this structure from my machine little-endianto the machine big-endian. I am not sure how to do this.

I have studied usage htons, but I'm not sure if this is applicable in this situation, as it seems to be defined only for unsigned ints16 or 32 bits, if I understood correctly.

+1
source share
3 answers

I think that there can be two problems depending on how you send this data over TCP.

1: Endianness

, , - . , htons ntohs . htonl .

Endianness . . 2- , , , .

, - ...

Sender:
-------
t.test     = 0xde; // Does not need to be swapped
t.test2[0] = 0xad; ... // Does not need to be swapped
t.test3[0] = 0xbe; ... // Does not need to be swapped
t.test4    = htons(0xdeca); // Needs to be swapped 

...

sendto(..., &t, ...);


Receiver:
---------
recvfrom(..., &t, ...);
t.test4    = ntohs(0xdeca); // Needs to be swapped 

htons() ntohs(), Ethernet... big endian. t.test4, big-endian (ntohs() noop ).

... Endian swapping

htons() , . ... Define byte format of buffer

Sender:
-------
uint8_t buffer[SOME SIZE];
t.test     = 0xde;
t.test2[0] = 0xad; ... 
t.test3[0] = 0xbe; ... 
t.test4    = 0xdeca;

buffer[0] = t.test;
buffer[1] = t.test2[0];
/// and so on, until...
buffer[7] = t.test4 & 0xff;
buffer[8] = (t.test4 >> 8) & 0xff;    

...

sendto(..., buffer, ...);

Receiver:
---------
uint8_t buffer[SOME SIZE];
recvfrom(..., buffer, ...);

t.test     = buffer[0];
t.test2[0] = buffer[1];
// and so on, until...
t.test4    = buffer[7] | (buffer[8] << 8);

, - , .

, , ...

2:

" : " - ..

, , - . , , , ...

struct
{
    uint8_t  v1;
    uint16_t v2; 
}

v2 1 , 2 , 4 ( ). , .

, 1 16- . , v2 . ? 2 h/w.

struct
{
    uint8_t  v1;
    uint8_t  invisible_padding_created_by_compiler;
    uint16_t v2; 
}

, , . , , / . .

+15

. , big-endian. hton/htons, . 8- - .

TCP nagle, , UDP .

+4

The data that you send over the network should be the same regardless of the limb of the machines used. The key word to explore is serialization . This means converting the data structure into a series of bits / bytes that must be sent over the network or stored on disk, which will always be the same regardless of architecture or compiler.

+1
source

All Articles