本文转自 https://blog.csdn.net/RuShrooM/article/details/25808297
主要处理tcp的json数据流,解析和除错json数据流,继承与 qtcpsocket层,方便扩展
数据流格式:
- #ifndef CONFIGTCPSOCKET_H
- #define CONFIGTCPSOCKET_H
- #include <QTcpSocket>
- #include <QJsonDocument>
- class JsonTcpSocket : public QTcpSocket
- {
- Q_OBJECT
- public:
- 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);
- }