I use a simple set of functions that I hand-wrote in C for writing all kinds of things to a buffer called a 'message'.
I have ones for writing 32-bit integers, floats.. Others for writing floats as a single byte, with a min/max range specified for the value. So if I have a float that's expected to be between -1 and 1 it will go ahead and pack it down into one byte, then on the other end a corresponding read function for re-constituting the original -1 to 1 float from the single byte.
I also have read/write functions for quaternions, angle-axis rotation velocities, of different bit counts so that in cases where I want to dispose of some accuracy for smaller amount of data, I can. A quat, for example, can be conveyed as either 24-bits, 32-bits or 64-bits. An angle-axis velocity can be conveyed in 40 bits or 64 bits. etc..
I can also read/write 3D vectors at varying bitdepths, specifying min/max values to map each vector component to all the bits allowed.
I don't think I will ever just read/write full on precision data structures, unless there's a case where that's absolutely necessary.