我正在使用sendto(..)和recvfrom()与通过UDP套接字运行相同程序的其他服务器(相同或相似系统)交换名为struct update_packet的结构。

基于来自stackoverflow.com/questions/27055729/的答案,我编写了一个函数来序列化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();
    }
                       ...
};


put_u16_as_big是一个辅助函数,它将Big Endian中的uint16_t放入引用的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]);
        }
    }
}


然后像

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


并发送。

我在cout中放入了一些serialize()进行测试。



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


它打印出看起来很奇怪的字符(框中的数字),大小为44。

但是,使用str.data()返回const char *

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


我懂了

    8


str.data()为空字符串,大小为8

此外,当我通过UDP套接字接收数据并打印来自recvfrom的返回值(即接收到的字节)时,它会打印0,并且接收到的消息与那种看起来很奇怪的字符相同,但只有一个字符。

有什么问题,如何解决此问题,以便可以在接收端接收和检索数据?

最佳答案

put_u16_as_big()中,您正在将原始二进制数据写入ostringstream(字符串),而没有实际将其转换为字符串。如果要写入原始二进制数据,则需要写入基本的ostream

另外,由于您实际上并未将其转换为字符串,因此无法像字符串一样将其打印出来。

如果您坚持使用ostringstream而不是使用oss.put()oss.write()来插入原始二进制文件,则应该使用operator<<来插入格式化的输出。当然,如果您真的在使用字符串,则字节序无关紧要。

关于c++ - 将结构序列化为char *并通过UDP发送,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/27071683/

10-09 07:42