Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>This is a very bad idea. Binary data should always be sent in a way that:</p> <ul> <li>Handles different <a href="http://en.wikipedia.org/wiki/Endianness" rel="noreferrer">endianness</a></li> <li>Handles different <a href="http://en.wikipedia.org/wiki/Data_structure_alignment#Data_Structure_Padding" rel="noreferrer">padding</a></li> <li>Handles differences in the <a href="https://en.wikipedia.org/wiki/Word_(computer_architecture)#Table_of_word_sizes" rel="noreferrer">byte-sizes of intrinsic types</a></li> </ul> <p>Don't ever write a whole struct in a binary way, not to a file, not to a socket.</p> <p>Always write each field separately, and read them the same way.</p> <p>You need to have functions like</p> <pre><code>unsigned char * serialize_int(unsigned char *buffer, int value) { /* Write big-endian int value into buffer; assumes 32-bit int and 8-bit char. */ buffer[0] = value &gt;&gt; 24; buffer[1] = value &gt;&gt; 16; buffer[2] = value &gt;&gt; 8; buffer[3] = value; return buffer + 4; } unsigned char * serialize_char(unsigned char *buffer, char value) { buffer[0] = value; return buffer + 1; } unsigned char * serialize_temp(unsigned char *buffer, struct temp *value) { buffer = serialize_int(buffer, value-&gt;a); buffer = serialize_char(buffer, value-&gt;b); return buffer; } unsigned char * deserialize_int(unsigned char *buffer, int *value); </code></pre> <p>Or the equivalent, there are of course several ways to set this up with regards to buffer management and so on. Then you need to do the higher-level functions that serialize/deserialize entire structs.</p> <p>This assumes serializing is done to/from buffers, which means the serialization doesn't need to know if the final destination is a file or a socket. It also means you pay some memory overhead, but it's generally a good design for performance reasons (you don't want to do a write() of each value to the socket).</p> <p>Once you have the above, here's how you could serialize and transmit a structure instance:</p> <pre><code>int send_temp(int socket, const struct sockaddr *dest, socklen_t dlen, const struct temp *temp) { unsigned char buffer[32], *ptr; ptr = serialize_temp(buffer, temp); return sendto(socket, buffer, ptr - buffer, 0, dest, dlen) == ptr - buffer; } </code></pre> <p>A few points to note about the above:</p> <ul> <li>The struct to send is first serialized, field by field, into <code>buffer</code>.</li> <li>The serialization routine returns a pointer to the next free byte in the buffer, which we use to compute how many bytes it serialized to</li> <li>Obviously my example serialization routines don't protect against buffer overflow.</li> <li>Return value is 1 if the <code>sendto()</code> call succeeded, else it will be 0.</li> </ul>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload