views:

110

answers:

6

Okay I hate to ask this question ... but here goes. I am writing some code in C on an x86 machine. I want to send a struct over the network and and I want to convert the struct to Network Byte Order ... I understand all the drama about packing and the the gcc packing pragmas ... what I want to know is HOW do I convert a struct (or an array or any such arbitrary memory blob) to network byte order.

Is there a standard (Unix/Linux/Posix) function call I can use or must I roll my own.

x

A: 

If you want to send data over the network, you will want to look at using the network-to-host and host-to-network byte ordering functions.

http://beej.us/guide/bgnet/output/html/multipage/htonsman.html

birryree
A: 

byteorder(3)

Ignacio Vazquez-Abrams
+7  A: 

In principle, you can go through the struct and call htonl or htons on each uint32_t or uint16_t field, respectively, assigning the results back or to a copy of the struct. However, I would not recommend this sort of approach. It's very fragile and subject to struct alignment issues, etc.

Unless transmitting and receiving data is extremely performance-critical, I would simply implement proper serialize and deserialize methods for your structures. You can write numeric values out one byte at a time in binary format, choosing whether you want to write to least significant or most significant part first. But really, I would recommend choosing a modern text-based serialization format like json or (uhg, I hate to say this) xml. The cost of serializing and deserializing text is quite small, and the advantages in terms of debugging ease and extensibility are significant.

Finally, if you want to use text but find json or xml too distasteful, too heavy, or too much of a learning curve, you can always just use printf and scanf formatting to read and write structures as text in a fixed order. Writing all numeric values, including floats, in hex rather than decimal will probably improve performance a bit and ensure round-trip accuracy of floating point values. If you don't have C99, another option for floats could be to decompose them to mantissa/exponent form and recompose them using frexp and ldexp.

R..
Agree, but I would avoid text anyway. If your code will run on both sides of the pipe, it's actually very easy to make it work using just binary data. Just take care of alignment (`#pragma pack(1)`) and of actual endianness of the data stream (and don't forget to correct the floating types, too).
ruslik
props for hating to say XML. switching to text is pedantic, but for most cases much better
Matt Joiner
`#pragma pack` is not remotely portable, and compilers for architectures where unaligned access is not possible would have to go to great lengths to implement it. If you're writing structures to be sent over a network in binary form, you should simply use fixed-size types of sizes 1, 2, or 4-byte, and order them such that even if they each require alignment equal to their size, there will be no padding.
R..
A: 

RESPONSE: Thank you for the responses. I guess the CORRECT answer is that for structs, arrays and such memory blobs you MUST implement your own serialization function ... this is fine ... I will look into this. I wanted to get a good feel before I attempted such a thing ...

x

Xofo
This place is for answers only. Consider removing and reposting it as a comment on your own question, or on the respective answer. By the way, WHY do you have 2 USERS with the same name?
jweyrich
I will figure out how to delete my MPD ...
Xofo
A: 

Also look into frameworks that have been implemented to tackle this exact problem, that allow you to marshall / demarshall arbitrarily complex data structures. If you are going to do this on a scale any larger than a few types, then use a framework.

  1. rpcgen / XDR : Don't let all the talk about RPC / client / server scare you away. You can use rpcgen to generate XDR marshalling / demarshalling routines for your data, that you can transport whichever way you like.
  2. Flick IDL Compiler Kit
  3. CORBA : Most CORBA frameworks have IDL compilers e.g. ACE TAO.
  4. ASN.1 : If you enjoy some pain. Very exotic though.
Ziffusion
I'd add protobuf-c :-)
jweyrich
tpl too http://tpl.sourceforge.net/ or c11n http://s11n.net/c11n/
Xofo