C ++ UDP получает вектор внутри класса - PullRequest
1 голос
/ 11 ноября 2011

Моя программа использует UDP для отправки данных между двумя программами, она прекрасно работает, однако я добавил новый вектор в данные, которые я хочу отправить, тип вектора - это другой класс, который выглядит следующим образом ...

class Bullet: public Sprite
{
public:
    float speed;
};

Пакет данных ...

typedef struct DataPacket
{
    int ID;                             //Player ID
    int elapsedTime;                    //Total elapsed player time
    float x, y;                         //X & Y pos of player
    std::vector<Bullet>* pBullets;      //Vector containing all the players bullets
};

Есть ли способ правильно отправить эти данные? Выражение не может быть оценено, как только сервер получит данные от клиента, каждая другая часть верна в полученном пакете.

Обычно сервер получает данные о позициях пуль на экране, которые содержатся в этом классе пуль, а также некоторые другие элементы.

Просто чтобы заметить: pBullet никогда не был указателем, но, пытаясь выяснить, в чем дело, я изменил его на указатель ... он никогда не решал проблему, хотя

Ответы [ 4 ]

3 голосов
/ 11 ноября 2011

Вы не можете сделать это. Вектор - это класс, который обычно реализуется с внутренним указателем на динамическую память, который меняет местоположение по мере роста вектора.

Когда вы пытаетесь сериализовать вектор путем приведения всей вашей структуры, вы просто сериализуете указатель на память, содержащую содержимое вектора, вы не получаете само содержимое, потому что оно не является частью этой структуры.

Вам придется индивидуально сериализовать все элементы в векторе один за другим и отдельно добавить их обратно при десериализации.

Обратите внимание, что вы можете изменить вектор пуль на массив статического размера внутри структуры, и тогда он будет непрерывным в памяти, и вы можете просто сериализовать всю структуру - и вы также можете сделать последний элемент массива массив из одного маркера, а затем выделите память для структуры size + (x-1) * sizeof (Bullet), что позволит вам перезаписать массив 1 для всей дополнительной памяти, которую вы добавили. Это также может быть непрерывным в памяти, что позволяет довольно легко сериализовать всю область памяти.

Вам также следует обратиться к htonl, ntohl, htons, ntohs и начать упорядочивать байты в сети, а также, если вы собираетесь отправлять их по сети, чтобы исключить возможность байтовой байтовости для некоторых других системы, которые вы можете использовать.

1 голос
/ 11 ноября 2011

Для разработки игр я бы рекомендовал использовать Google ProtoBuf .По сравнению с Boost Serialization она обеспечивает двоичную сериализацию (Boost Serialization имеет пример двоичной сериализации, но она не очень переносима) и более удобна для сложных структур данных.

1 голос
/ 11 ноября 2011

Используйте сериализацию всякий раз, когда вам нужно отправить данные по сети. Вы можете сослаться на Boost Serialization . Ваш DataPacket имеет динамический размер. Если бы это был массив, а не вектор, он мог бы работать с той же порядковой точностью машин.

0 голосов
/ 11 ноября 2011

Вам необходимо сериализовать данные самостоятельно. Вы не можете просто отправить std::vector или указатель на него.

...