Eric
Eric

Reputation: 2705

converting struct to general message format to be passed to UDP

I have a C++ struct for an update packet to be exchanged between servers, and another struct to implement information about neighbors, and a vector of struct neighbor is inside update packet.

struct neighbor;
struct update_packet {
    uint16_t num_update_fields;
    uint16_t port;
    uint32_t IP;

    vector<struct neighbor> neighbors;

    update_packet(char * IPstr, int port) :
        num_update_fields(num_nodes),
        IP(IP_to_int(IPstr)), port((uint16_t) port)
        { };
};

struct neighbor {
    uint32_t IP;
    uint16_t port;
    int16_t nil;
    uint16_t server_id;
    uint16_t cost;

    neighbor(char * IPstr, uint16_t port, uint16_t server_id, uint16_t cost) :
        IP(IP_to_int(IPstr)), port(port), nil(0),
        server_id(server_id), cost(cost) { };
};

I want to exchange this struct in general message format (like IP datagram, for example) through UDP sockets and read the information in the message on the receiving end.

How can I achieve this? Is my design for the structs a poor design for my purpose?

Upvotes: 0

Views: 611

Answers (2)

berkus
berkus

Reputation: 1563

Slightly more c++ style serialization and deserialization is desribed in this article - https://rodgert.github.io/2014/09/09/type-driven-wire-protocols-with-boost-fusion-pt1/

Upvotes: 1

Jay Miller
Jay Miller

Reputation: 2234

What you're asking about is serialization. At it's simplest, if you have a POD type and know that the machines at both ends are the same type you can just cast and send:

struct Foo {
  uint32_t a;
  uint16_t p;
};

Foo f { 1, 2 };
sendto(targetFD, reinterpret_cast<const char*>(&f), sizeof(f), 0);

Your structure couldn't be used this way because of the vector. The data in a vector is dynamically allocated so it isn't laid out with the rest of the structure. If you need a variable length field like this, an array (or a std::array) along with an indicator of the number of elements would be useful.

Casting structures like this is fast but not really portable. If you want to be able to pass to other languages or platforms you would prefer a serialization format. Google's Protocol Buffers (https://code.google.com/p/protobuf/) and several other serialization libraries are designed to allow this.

Upvotes: 1

Related Questions