標籤:blog class code c ext http
主要處理tcp的json資料流,解析和除錯json資料流,繼承與 qtcpsocket層,方便擴充
資料流格式:
#ifndef CONFIGTCPSOCKET_H#define CONFIGTCPSOCKET_H#include <QTcpSocket>#include <QJsonDocument>class JsonTcpSocket : public QTcpSocket{ Q_OBJECTpublic: explicit JsonTcpSocket(QObject *parent = 0); virtual ~JsonTcpSocket(); const QString &getLastError()const{return lastErrorString;} const int &getLastCode()const{return lastErrorCode;}public slots: bool write(const char *json); bool write(const QJsonDocument &json); bool write(const QByteArray &json); bool write(const QString &json); bool write(const QJsonObject &obj);signals: void newJsonData(const QJsonDocument &doc);//新的json資料 void jsonError(const int &errorCode,const QString &errorString);//json格式錯誤 void socketError(const int &errorCode,const QString &errorString);//網路錯誤private slots: void readBytes();//讀取位元組 void networkError(QAbstractSocket::SocketError error);//網路錯誤private: int readByteCount=0; QString lastErrorString; //最後的錯誤文字 int lastErrorCode;//錯誤碼};#endif // CONFIGTCPSOCKET_H
#include "jsontcpsocket.h"#include <QDataStream>#include "settingconfig.h"#include <QByteArray>#include <QThread>#include "commonfunction.h"JsonTcpSocket::JsonTcpSocket(QObject *parent) : QTcpSocket(parent){ connect(this,&JsonTcpSocket::readyRead,this,&JsonTcpSocket::readBytes); connect(this,SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(networkError(QAbstractSocket::SocketError))); this->setSocketOption(QAbstractSocket::LowDelayOption,"1"); //啟用nagle低延遲演算法 this->setSocketOption(QAbstractSocket::KeepAliveOption,"1"); //設定保持串連狀態}JsonTcpSocket::~JsonTcpSocket(){}void JsonTcpSocket::readBytes()//讀取位元組{ if(this->readByteCount==0) { char peek; this->read(&peek,sizeof(peek)); if(peek==‘l‘) //查看是否是資料包的起始位置 { char len[READ_RAW_LEN];//讀取json資料的長度 this->read(len,sizeof(len)); ByteToInt(len,&this->readByteCount); }else //否則就丟棄全部的資料 { this->readAll(); //qDebug()<<"read all data:"<<this->readAll(); return; } } if(this->readByteCount>this->bytesAvailable()) return; char *json=new char[this->readByteCount]; this->read(json,this->readByteCount); //讀取json資料 this->readByteCount=0; //資料長度重設為0; QJsonParseError parseError; QJsonDocument jsonDoc(QJsonDocument::fromJson(json,&parseError)); if(parseError.error==QJsonParseError::NoError) //json格式是否正確 { // qDebug()<<"read json data:"<<jsonDoc.toJson(); emit newJsonData(jsonDoc); //發送json資料訊號 } else { this->lastErrorCode=parseError.error; this->lastErrorString=parseError.errorString(); emit jsonError(parseError.error,parseError.errorString()); //發送錯誤碼 qDebug()<<"json format error:"<<json; } delete []json; this->readBytes(); //繼續讀取一下段資料}bool JsonTcpSocket::write(const char *json){ return this->write(QJsonDocument::fromJson(json));}bool JsonTcpSocket::write(const QByteArray &json){ return this->write(QJsonDocument::fromJson(json));}bool JsonTcpSocket::write(const QString &json){ return this->write(QJsonDocument::fromVariant(json));}bool JsonTcpSocket::write(const QJsonObject &obj){ return this->write(QJsonDocument(obj));}bool JsonTcpSocket::write(const QJsonDocument &json){ QByteArray array; array.prepend(json.toJson(QJsonDocument::Compact)); int len=array.length(); char lenByte[READ_RAW_LEN]; IntToByte(len,lenByte); array.prepend(lenByte,sizeof(lenByte)); array.prepend(‘l‘); int bytes=-1; bytes=QTcpSocket::write(array); return bytes!=-1;}void JsonTcpSocket::networkError(QAbstractSocket::SocketError error)//網路錯誤{ this->lastErrorString=this->errorString(); this->lastErrorCode=error; emit socketError(error,this->lastErrorString);}