1. Network data reception
Use QTcpSocket or QUdpSocket to receive data and trigger read through the readyRead() signal:
// Create a TCP Socket and connect to the signalQTcpSocket *socket = new QTcpSocket(this); connect(socket, &QTcpSocket::readyRead, [=](){ QByteArray data = socket->readAll(); processData(data); });
2. Buffer management (handling sticking/unpacking)
It is recommended to use member variables to save unprocessed data:
class NetworkHandler : public QObject { QByteArray m_buffer; // Class member variableprivate slots: void onReadyRead() { m_buffer += socket->readAll(); while(parseBuffer()); // Loop analysis } bool parseBuffer() { if(m_buffer.size() < 4) return false; // Example: Assume that the first 4 bytes are length headers quint32 packetLength; QDataStream ds(m_buffer); ds >> packetLength; if(m_buffer.size() < packetLength + 4) return false; QByteArray packet = m_buffer.mid(4, packetLength); handlePacket(packet); m_buffer.remove(0, packetLength + 4); return true; } };
3. Common data format analysis
3.1 JSON parsing
void parseJson(const QByteArray &data) { QJsonParseError error; QJsonDocument doc = QJsonDocument::fromJson(data, &error); if( != QJsonParseError::NoError) { qDebug() << "JSON Error:" << (); return; } QJsonObject obj = (); QString value = obj["key"].toString(); }
3.2 XML parsing
void parseXml(const QByteArray &data) { QXmlStreamReader xml(data); while(!()) { (); if(()) { if(() == "item") { QString attr = ().value("id").toString(); } } } if(()) { qDebug() << "XML Error:" << (); } }
3.3 Custom binary protocol
#pragma pack(push, 1) struct CustomHeader { quint16 magic; // Protocol ID 0xABCD quint32 length; // Data part length quint8 version; // Protocol version}; #pragma pack(pop) void parseCustomProtocol(const QByteArray &data) { if(() < sizeof(CustomHeader)) return; CustomHeader header; memcpy(&header, (), sizeof(header)); if( != 0xABCD) return; QByteArray payload = (sizeof(header), ); // Handle payload...}
4. Coding processing
// UTF-8 conversion exampleQString decodeString(const QByteArray &data) { QTextCodec *codec = QTextCodec::codecForName("UTF-8"); return codec->toUnicode(data); } // Process binary datavoid processBinary(const QByteArray &data) { QDataStream stream(data); (QDataStream::LittleEndian); quint32 num; QString str; stream >> num >> str; }
5. Complete processing flow example
class NetworkProcessor : public QObject { QTcpSocket *socket; QByteArray buffer; public: NetworkProcessor() { socket = new QTcpSocket(this); connect(socket, &QTcpSocket::readyRead, this, &NetworkProcessor::readData); } private slots: void readData() { buffer += socket->readAll(); while(true) { if(() < 4) return; quint32 packetLength; QDataStream ds(buffer); ds >> packetLength; if(() < packetLength + 4) return; QByteArray packet = (4, packetLength); processPacket(packet); (0, packetLength + 4); } } void processPacket(const QByteArray &packet) { // Choose the parsing method according to the protocol type if(isJsonProtocol(packet)) { parseJson(packet); } else if(isBinaryProtocol(packet)) { parseBinary(packet); } } };
6. Things to note
- Byte order processing: When using QDataStream, it is used by default. It can be modified by setByteOrder().
- Memory management: Avoid frequent memory allocation and pre-allocate buffers
- Timeout processing: For incomplete packets, you need to set a timeout mechanism.
- Security verification: Verify the legality of the field (such as the maximum limit of the length field)
- Performance optimization: Zero copy technology can be considered for high-frequency data (such as QByteArray::fromRawData)
For high-level protocols such as HTTP, it is recommended to directly use advanced APIs such as QNetworkAccessManager to avoid manual parsing.
This is the end of this article about the summary of Qt's methods to implement network data analysis. For more related Qt data analysis content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!