如何写一个通用的网络包?

namespace packet {
/*!
|magic|type|length|data|checksum|
|4	  |4   |4     |    |2       |
*/
#pragma pack(push)
#pragma pack(1)

class IPacket
{
public:
	virtual ~IPacket() = default;
protected:
	virtual QByteArray sendData(const QByteArray &data) = 0;
	virtual IPacket &receiveData(const QByteArray &data) = 0;
	virtual quint32 type() const = 0;
	virtual bool isVaild() = 0;
	virtual bool isEqual(quint32 type) = 0;
};

constexpr quint32 magic = (quint32)0x49506B74;//IPkt asscii

class Packet : public IPacket
{
public:
	enum Type:quint32 {
		UserType = 1
	};
	QByteArray sendData(const QByteArray &data) override {
		QByteArray byte;
		QDataStream out(&byte, QIODevice::WriteOnly);
		out << magic;
		out << this->type();
		out << (quint32)data.length();
		out.writeRawData(data.data(), data.size());
		out << qChecksum(data.data(), data.length());
		return byte;
	}
	Packet &receiveData(const QByteArray &data) override {
		QDataStream in(data);
		in >> m_magic;
		in >> m_type;
		in >> m_length;
		m_raw.resize(m_length);
		in.readRawData(m_raw.data(),m_length);
		in >> m_checksum;
		return *this;
	}
	quint32 type() const override {
		return UserType;
	}
	bool isVaild() override {
		return m_checksum == qChecksum(m_raw.data(), m_raw.length()) ? true : false;
	}
	bool isEqual(quint32 type) override {
		return type == m_type ? true : false;
	}
	quint32 m_magic;
	quint32 m_type;
	quint32 m_length;
	QByteArray m_raw;
	quint16 m_checksum;
};

struct alignas(alignof(quint32)) PacketHeader
{
	void sequence(const QByteArray &data) {
		QDataStream in(data);
		in >> m_magic;
		in >> m_type;
		in >> m_length;
	}
	bool isValid() {
		return (magic == magic && m_type > 0 && m_length > 0) ? true : false;
	}
	quint32 m_magic{ 0 };
	quint32 m_type{ 0 };
	quint32 m_length{ 0 };
};

#pragma pack(pop)
}
posted @ 2021-02-02 10:54  學海無涯  阅读(84)  评论(0编辑  收藏  举报