/* * msg_client.h — C++ транспортный клиент для chat GUI * * Подключается к utun msg_transport по localhost TCP. * Протокол: [size:2][type:1][id:8][options:1][data...] (msg_transport.h). */ #ifndef MSG_CLIENT_H #define MSG_CLIENT_H #include #include #include #include class MsgClient : public QObject { Q_OBJECT public: explicit MsgClient(QObject* parent = nullptr); ~MsgClient() override; void connectToHost(const QString& host, quint16 port); void disconnectFromHost(); bool isConnected() const; void bind(quint64 peerId); void unbind(); bool isBound() const { return m_boundPeerId != 0; } quint64 boundPeerId() const { return m_boundPeerId; } void send(const QByteArray& data); void send(const uint8_t* data, size_t len); void sendSigned(const QByteArray& data); signals: void connected(); void disconnected(); void bound(quint64 peerId); void unbound(); void received(quint64 peerId, const QByteArray& data); void errorOccurred(uint8_t code, const QString& message); private: static constexpr size_t kMaxMsgSize = 8192; static constexpr uint8_t kCtlBind = 0x01; static constexpr uint8_t kCtlUnbind = 0x02; static constexpr uint8_t kDataSend = 0x10; static constexpr uint8_t kDataRecv = 0x11; static constexpr uint8_t kRspBindOk = 0xE1; static constexpr uint8_t kRspError = 0xFF; static constexpr uint8_t kOptSigned = 0x01; static constexpr size_t kHdrSize = 12; QTcpSocket* m_socket; QByteArray m_recvBuffer; quint64 m_boundPeerId = 0; void onReadyRead(); void onSocketError(QAbstractSocket::SocketError); void processMessages(); void dispatch(uint8_t type, quint64 id, const QByteArray& payload); QByteArray buildMessage(uint8_t type, quint64 id, uint8_t options, const QByteArray& data); }; #endif // MSG_CLIENT_H