简体   繁体   中英

Serializing struct to char * and sending it over UDP

I am exchanging a struct called struct update_packet with other servers (of identical or similar system) running the same program through UDP socket using sendto(..) and recvfrom().

Based on answers from stackoverflow.com/questions/27055729/, I wrote a function to serialize struct update_packet

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

    vector<struct node> nodes;

    const char * serialize() const {
        ostringstream oss;
        put_u16_as_big(oss, num_update_fields);
        put_u16_as_big(oss, port);
        put_u32_as_big(oss, IP);

        for(size_t i = 0; i < num_update_fields; ++i) {
            put_u32_as_big(oss, nodes[i].IP);
            put_u16_as_big(oss, nodes[i].port);
            put_u16_as_big(oss, nodes[i].nil);
            put_u16_as_big(oss, nodes[i].server_id);
            put_u16_as_big(oss, nodes[i].cost);
        }
        string str = oss.str();

        cout << str << "\t" << str.size() << endl;
        cout << str.data() << "\t" << sizeof(str.data()) << endl;
        return str.data();
    }
                       ...
};

and put_u16_as_big is a helper function that puts a uint16_t in Big Endian to a referenced ostringstream .

void put_u16_as_big(ostringstream& oss, uint16_t data) {
    if (is_big_endian()) {
        oss.write((const char *)&data, sizeof(data));
    }
    else {
        const char * ptr = (const char *)&data;
        unsigned int s = sizeof(data);
        for(unsigned int i=0; i < s; ++i) {
            oss.put(ptr[s-1-i]);
        }
    }
}

Then it is instantiated like

struct update_packet up;
const char * up_to_send = up.serialize();

and sent.

I put some cout in serialize() for testing.

With

cout << str << "\t" << str.size() << endl;

It prints weird looking characters (numbers in a box) and the size is 44.

However, with str.data() which returns const char *

cout << str.data() << "\t" << sizeof(str.data()) << endl;

I get

    8

empty string for str.data() and 8 for size

Moreover, when I receive the data through UDP socket and print the return value from recvfrom which is the byte received, it prints 0, and the received message is the same kind as that weird looking character, but only one character.

What is the problem, and how can I fix this so that I could receive and retrieve data on the receiving side?

in put_u16_as_big() , you're writing raw binary data into a ostringstream (a string) without actually converting it to a string. If you want to write raw binary data you need to write to a basic ostream .

Also since you're not actually converting it to a string you can't print it out as though it were a string.

If you insist on using ostringstream then instead of using oss.put() and oss.write() which will insert raw binary you should use operator<< which will insert formatted output. Of course if you're really using strings then endianness doesn't matter.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM