SFML网络|通过sf :: Packets发送包含其他对象的对象会导致空数据

时间:2017-06-10 14:11:30

标签: c++ networking sfml

我正在尝试将地图数据发送到客户端,该客户端采用包含地图图块坐标的多个向量的形式。整个地图结构可以简化为这样的(不是实际的代码,但我也用这个重现了问题):

struct Tile {
    sf::Vector3<int> coords;
};

struct Map {
    Tile tiles[4];
};

然后,我使用这些运算符将此类对象添加到sf::Packet

sf::Packet& operator<<(sf::Packet& packet, sf::Vector3<int> vec) {
    return packet << vec.x << vec.y << vec.z;
}

sf::Packet& operator>>(sf::Packet& packet, sf::Vector3<int> vec) {
    return packet >> vec.x >> vec.y >> vec.z;
}

sf::Packet& operator<<(sf::Packet& packet, Tile test) {
    return packet << test.coords;
}

sf::Packet& operator>>(sf::Packet& packet, Tile test) {
    return packet >> test.coords;
}

sf::Packet& operator<<(sf::Packet& packet, Map test) {
    for(int i = 0; i < 4; i++) {
        packet << test.tiles[i];
    }
    return packet;
}

sf::Packet& operator>>(sf::Packet& packet, Map test) {
    for(int i = 0; i < 4; i++) {
        packet >> test.tiles[i];
    }
    return packet;
}

到此为止,不应该出现任何问题:必须将地图反序列化为4个图块,必须将其反序列化为sf::Vector3<int>本身。

然后发送:

Tile test;
test.coords.x = 42;
test.coords.y = 34;
test.coords.z = 43;

Map test3;
test3.tiles[0] = test;

sf::Packet packet;
packet << test3;

sock.send(packet);

这段代码效果很好(我用GDB检查了packet的内容,数据确实相同)。接收代码在服务器端也很有效:

sf::Packet packet;
sock.receive(packet);
Map test;
cout << "packet received" << endl;

检查数据包的内容(仍然使用GDB)提供与发送时相同的内容。 test的内容是随机的(这是正常的,因为它还没有被初始化)。

将实际数据包数据反序列化为test变量时会发生真正的问题:

if(packet >> test) {
    cout << test.tiles[0].coords.x;
} else {
    cout << "fail" << endl;
}

打印结果为0.反序列化表现良好(没有&#34;失败&#34;出现在控制台中),但数据不正确。使用GDB检查test的内容会显示其数组为0的每个元素。这是GDB的输出:

(gdb) print test
$1 = {tiles = {{coords = {x = 0, y = 0, z = 0}}, {coords = {x = 0, y = 0, z = 0}}, {coords = {x = 0, y = 0, z = 0}}, {coords = {
        x = 0, y = 0, z = 0}}}}

这可能是什么原因?我很确定我在这里做错了什么,但我真的无法理解。

提前感谢您的任何帮助:)

1 个答案:

答案 0 :(得分:1)

好的,我终于明白了为什么这不起作用。 答案当然是非常愚蠢的,而且是典型的傻C ++初学者:D。

使用操作符函数而不通过引用传递对象没有一次机会工作(因为变量的内容将保留在操作符函数中而不会被更改)。

所以,改变这个:

sf::Packet& operator>>(sf::Packet& packet, Map test) {
    for(int i = 0; i < 4; i++) {
        packet >> test.tiles[i];
    }
    return packet;
}

到此:

sf::Packet& operator>>(sf::Packet& packet, Map& test) {
    for(int i = 0; i < 4; i++) {
        packet >> test.tiles[i];
    }
    return packet;
}

效果更好:)