注意:網(wǎng)絡(luò)編程需要在pro文件里添加 network,如該用到qSqldatabase 需要添加sql
例:
QT+= network\
? ? sql
#一侠姑、QTcpsocket:
QTcpsocet 是QT提供的tcp/ip的四層socket類.TCP(傳輸控制協(xié)議)是一種可靠的嗦明,面向流的廉赔,面向連接的傳輸協(xié)議灸叼。它特別適用于連續(xù)傳輸數(shù)據(jù)汉额。
QTcpsocket 是QAbstractSocket的子類.
方法:
QTcpsocet::connectToHost(str 'ip', int port, QIODevice::ReadWrite) //連接socket
?QTcpsocket::write(QBytearry) //數(shù)據(jù)的寫入
虛構(gòu)函數(shù):
void QTcpsocket::readyRead() //實現(xiàn)接收到數(shù)據(jù)時執(zhí)行
二、QTcpServer: socket _server
例子:?
頭文件
```
#ifndef TCP_SERVER_H
#define TCP_SERVER_H
#include <QTcpServer>
#include <QTcpSocket>
#include <QJsonObject>
#include <QObject>
class tcp_server : public QTcpServer //重寫QTcpServer
{
? ? Q_OBJECT
public:
? ? tcp_server(); //構(gòu)造函數(shù)
? ? QByteArray data_length_data(QByteArray data);? //用于對要發(fā)送的數(shù)據(jù)頭部添加包長度被冒。
protected:
? ? void incomingConnection(qintptr soketnember); //有新連接時執(zhí)行军掂,創(chuàng)造socket連接。
signals:
public slots:
? ?// void socket_write(QJsonObject user_passwd,QTcpSocket *tcpsocket);
};
class tcp_socket : public QTcpSocket? //重寫tcpsocket
{
? ? Q_OBJECT
public:
? ? tcp_socket(qintptr soketDescriptor, QTcpSocket *parent=NULL); // soketDescriptor socket號昨悼。?
? ? void router(); //接收數(shù)據(jù)路由蝗锥。
? ? QByteArray data_length_data(QByteArray data); //對發(fā)送的數(shù)據(jù)添加包長度
private:
? ? int m_tcpBlockSize = 0;? ? ? ? //數(shù)據(jù)包長度計算
? ? bool is_one;? ? ? ? ? ? ? ? ? ? //是否是第一個數(shù)據(jù)包
? ? int data_length;? ? ? ? ? ? //數(shù)據(jù)包長度
? ? QByteArray read_data;? ? //數(shù)據(jù)包緩存(在接收到的數(shù)據(jù)包未達(dá)到第一個包描述的大小時緩存用)
? ? //sql db;
signals:
? ? ? ? void return_db(QJsonObject user_passwd,QTcpSocket *tcpsocket); //查詢數(shù)據(jù)庫信號,qsqldatabase 的多線程問題率触,所有發(fā)送信號到主進(jìn)程终议。
private slots:
? ? void Read_data(); //有數(shù)據(jù)進(jìn)來時調(diào)用
};
#endif // TCP_SERVER_H
'''
.cpp部分:
#include "tcp_server.h"
#include <QTcpServer>
#include <QThread>
#include <QDebug>
#include <QString>
#include <QDataStream>
#include <QJsonObject>
#include <QJsonArray>
#include <QByteArray>
#include <QJsonDocument>
//#include <QJsonObject>
#include "sql.h"? //數(shù)據(jù)庫查詢,寫入部分葱蝗,于本筆記無關(guān)可忽略
#include "cache.h" //全局變量穴张,用于緩存最后一次的值,于本筆記無關(guān)两曼,可忽略
tcp_server::tcp_server()
{
}
void tcp_server::incomingConnection(qintptr soketnember){ //有新連接時執(zhí)行
? ? tcp_socket * socket=new tcp_socket(soketnember); //創(chuàng)建一個socket連接指針并按“本機(jī)套接字描述符”創(chuàng)建
? ? QThread *task=new QThread(); 創(chuàng)建一個線程地址皂甘。
? ? connect(socket,SIGNAL(disconnected()),task,SLOT(quit()));? //socket斷開連接時退出線程
? ? connect(socket,SIGNAL(readyRead()),socket,SLOT(Read_data())); //有數(shù)據(jù)傳入時執(zhí)行Read_data()槽
? ? connect(socket,SIGNAL(return_db(QJsonObject,QTcpSocket*)),this,SLOT(socket_write(QJsonObject,QTcpSocket*))); //用于解決QSqldatabase 多線程問題,在需要查詢數(shù)據(jù)庫時發(fā)送給主進(jìn)程執(zhí)行悼凑,由主進(jìn)程直接返回給客戶端的socket 偿枕。
? ? socket->moveToThread(task); //移動socket 到線程
? ? task->start(); //線程啟動
}
void tcp_server::socket_write(QJsonObject user_password,QTcpSocket *tcpsocket){
? ? sql db; //初始化數(shù)據(jù)庫類,此類為自定義類佛析,與本筆記無關(guān)
? ? qDebug()<<user_password;
? ? QString user=user_password.value("user").toString();
? ? QString password=user_password.value("password").toString();
? ? QJsonObject login_status=db.login(user,password);
? ? QJsonObject data_send;
? ? data_send.insert("type","login");
? ? data_send.insert("data",login_status);
? ? tcpsocket->write(data_length_data(QJsonDocument(data_send).toJson())); //socket 直接返回給客戶端
? ? tcpsocket->waitForBytesWritten(1000); //寫超時設(shè)定為1秒益老。
}
tcp_socket::tcp_socket(qintptr soketDescriptor, QTcpSocket *parent) :QTcpSocket(parent)
{
? ? this->setSocketDescriptor(soketDescriptor); //設(shè)置這個連接的描述符是由QTcpserver傳入的連接描述符彪蓬。
}
void tcp_socket::Read_data(){? //讀取數(shù)據(jù)
? ? if(m_tcpBlockSize==0){ //判斷已接收的數(shù)據(jù)是否為0,0表示第一個數(shù)據(jù)包寸莫。
? ? ? QByteArray dd=this->readAll(); //讀出所有數(shù)據(jù)。
? ? ? QDataStream cc(&dd,QIODevice::ReadWrite); //以流數(shù)據(jù)方式打開
? ? ? cc.device()->seek(0); //設(shè)置數(shù)據(jù)指針為0.
? ? ? cc>>data_length; //獲取數(shù)據(jù)包大小档冬。所以要求客戶段傳來的數(shù)據(jù)包前4個byte時int的包大小膘茎。
? ? ? if(!data_length>8){
? ? ? ? ? this->disconnect();
? ? ? ? ? this->close();
? ? ? }
// 包描述: qbytearry [int(包大小),xxxxxxxxxxxxxxxxxxxxxxx.......數(shù)據(jù)部分]
? ? ? cc.device()->seek(sizeof(int)); //移動指針到包大小描述后的數(shù)據(jù)開始位。
? ? ? ? while (!cc.atEnd()) { //循環(huán)判斷數(shù)據(jù)是否讀取到結(jié)尾
? ? ? ? ? ? unsigned char tmp_char;
? ? ? ? ? ? cc>>tmp_char;
? ? ? ? ? ? read_data.append(tmp_char); //把每個byte追加到緩存中酷誓。
? ? ? ? }
//? ? ? ? qDebug()<<data_length<<read_data.size();
? ? ? ? if(data_length==read_data.size()){ //數(shù)據(jù)是否接收完成披坏。
//? ? ? ? ? ? qDebug()<<read_data;
? ? ? ? ? ? router(); //完成時調(diào)用路由
? ? ? ? }
? ? ? ? m_tcpBlockSize=1; //設(shè)置為1表示后面的包不在是第一個數(shù)據(jù)包
? ? ? ? cc.device()->close();
? ? }else { //不是第一個包時執(zhí)行
? ? ? ? QByteArray dd=this->readAll();?
? ? ? ? QDataStream cc(&dd,QIODevice::ReadWrite);
? ? ? ? while (!cc.atEnd()) {
? ? ? ? ? ? unsigned char tmp_char;
? ? ? ? ? ? cc>>tmp_char;
? ? ? ? ? ? read_data.append(tmp_char);
? ? ? ? }
? ? ? ? if(data_length==read_data.size()){
? ? ? ? ? ? router();
? ? ? ? }
? ? ? ? cc.device()->close();
? ? }
}
void tcp_socket::router(){ //路由部分
? ? if(QJsonDocument::fromJson(read_data).isObject()){
//? ? ? ? qDebug()<<read_data;
? ? ? ? QJsonObject data=QJsonDocument::fromJson(read_data).object();
? ? ? ? if(data.keys().contains("type")){
? ? ? ? ? ? QString type=data.value("type").toString();
? ? ? ? ? ? if(type=="last_temperatuer"){
? ? ? ? ? ? ? ? //返回最后一次溫度
? ? ? ? ? ? ? ? QJsonObject data_send;
? ? ? ? ? ? ? ? data_send.insert("type","last_temperatuer");
? ? ? ? ? ? ? ? data_send.insert("data",last_temperatuer);
? ? ? ? ? ? ? ? QByteArray byte_data=QJsonDocument(data_send).toJson();
? ? ? ? ? ? ? ? this->write(data_length_data(byte_data));
? ? ? ? ? ? }else if(type=="last_wendu_collector"){
? ? ? ? ? ? ? ? // insert 返回最后一次溫度
? ? ? ? ? ? ? ? QJsonArray tmp_arry;
? ? ? ? ? ? ? ? QJsonObject send_data=data.value("data").toObject();
? ? ? ? ? ? ? ? last_temperatuer=tmp_arry;
? ? ? ? ? ? ? ? for(int i=0;i<send_data.keys().length();i++){
? ? ? ? ? ? ? ? ? ? QString key=send_data.keys()[i];
? ? ? ? ? ? ? ? ? ? QJsonObject tmp_data;
? ? ? ? ? ? ? ? ? ? tmp_data.insert(key,send_data.value(key).toInt());
? ? ? ? ? ? ? ? ? ? last_temperatuer.append(tmp_data);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? else if (type=="temperatuer_day_hour") {
? ? ? ? ? ? ? ? int day=data.value("day").toInt();
? ? ? ? ? ? ? ? QString temperatuer_type=data.value("temperatuer_type").toString();
? ? ? ? ? ? ? ? QJsonArray data_list=db.day_hour_temperatuer(day,temperatuer_type);
? ? ? ? ? ? ? ? QJsonObject data_send;
? ? ? ? ? ? ? ? data_send.insert("type","temperatuer_day_hour");
? ? ? ? ? ? ? ? data_send.insert("data",data_list);
? ? ? ? ? ? ? ? QByteArray byte_data=QJsonDocument(data_send).toJson();
? ? ? ? ? ? ? ? this->write(data_length_data(byte_data));
? ? ? ? ? ? }else if (type=="temperatuer_ri") {
? ? ? ? ? ? ? ? //按日返回
? ? ? ? ? ? ? ? QString temperatuer_type=data.value("temperatuer_type").toString();
? ? ? ? ? ? ? ? QJsonArray data_list=db.temperatuer_ri(temperatuer_type);
? ? ? ? ? ? ? ? QJsonObject data_send;
? ? ? ? ? ? ? ? data_send.insert("type","temperatuer_ri");
? ? ? ? ? ? ? ? data_send.insert("data",data_list);
? ? ? ? ? ? ? ? QByteArray byte_data=QJsonDocument(data_send).toJson();
? ? ? ? ? ? ? ? this->write(data_length_data(byte_data));
? ? ? ? ? ? }else if (type=="temperatuer_yue") {
//? ? ? ? ? ? ? ? qDebug()<<type;
? ? ? ? ? ? ? ? //按日返回
? ? ? ? ? ? ? ? QString temperatuer_type=data.value("temperatuer_type").toString();
//? ? ? ? ? ? ? ? sql db;
? ? ? ? ? ? ? ? QJsonArray data_list=db.temperatuer_yue(temperatuer_type);
? ? ? ? ? ? ? ? QJsonObject data_send;
? ? ? ? ? ? ? ? data_send.insert("type","temperatuer_yue");
? ? ? ? ? ? ? ? data_send.insert("data",data_list);
? ? ? ? ? ? ? ? QByteArray byte_data=QJsonDocument(data_send).toJson();
? ? ? ? ? ? ? ? this->write(data_length_data(byte_data));
? ? ? ? ? ? }else if (type=="temperatuer_zhou") {
//? ? ? ? ? ? ? ? qDebug()<<type;
? ? ? ? ? ? ? ? //按周返回
? ? ? ? ? ? ? ? QString temperatuer_type=data.value("temperatuer_type").toString();
? ? ? ? ? ? ? ? QJsonArray data_list=db.temperatuer_zhou(temperatuer_type);
? ? ? ? ? ? ? ? QJsonObject data_send;
? ? ? ? ? ? ? ? data_send.insert("type","temperatuer_zhou");
? ? ? ? ? ? ? ? data_send.insert("data",data_list);
? ? ? ? ? ? ? ? QByteArray byte_data=QJsonDocument(data_send).toJson();
? ? ? ? ? ? ? ? this->write(data_length_data(byte_data));
? ? ? ? ? ? }else if (type=="temperatuer_yue") {
? ? ? ? ? ? ? ? //按月返回
? ? ? ? ? ? ? ? QString temperatuer_type=data.value("temperatuer_type").toString();
? ? ? ? ? ? ? ? QJsonArray data_list=db.temperatuer_yue(temperatuer_type);
? ? ? ? ? ? ? ? QJsonObject data_send;
? ? ? ? ? ? ? ? data_send.insert("type","temperatuer_yue");
? ? ? ? ? ? ? ? data_send.insert("data",data_list);
? ? ? ? ? ? ? ? QByteArray byte_data=QJsonDocument(data_send).toJson();
? ? ? ? ? ? ? ? this->write(data_length_data(byte_data));
? ? ? ? ? ? }else if (type=="login") {
? ? ? ? ? ? ? ? return_db(data,this);
? ? ? ? ? ? }else if (type=="on_off") {
? ? ? ? ? ? ? QString user=data.value("user").toString();
? ? ? ? ? ? ? int value=data.value("value").toInt();
? ? ? ? ? ? ? ? QJsonObject on_off_status=db.set_action(user,type,value);
? ? ? ? ? ? ? ? QJsonObject data_send;
? ? ? ? ? ? ? ? data_send.insert("type","on_off");
? ? ? ? ? ? ? ? data_send.insert("data",on_off_status);
? ? ? ? ? ? ? this->write(data_length_data(QJsonDocument(data_send).toJson()));
? ? ? ? ? ? }else if (type=="set_moshi_leng_re") {
? ? ? ? ? ? ? ? QString user=data.value("user").toString();
? ? ? ? ? ? ? ? int value=data.value("value").toInt();
? ? ? ? ? ? ? ? QJsonObject moshi_leng_re=db.set_action(user,type,value);
? ? ? ? ? ? ? ? QJsonObject data_send;
? ? ? ? ? ? ? ? data_send.insert("type","set_moshi_leng_re");
? ? ? ? ? ? ? ? data_send.insert("data",moshi_leng_re);
? ? ? ? ? ? ? ? this->write(data_length_data(QJsonDocument(data_send).toJson()));
? ? ? ? ? ? }
? ? ? ? }else {
? ? ? ? ? ? this->disconnect();
? ? ? ? ? ? this->close();
? ? }
? ? }else {
? ? ? ? this->disconnect();
? ? ? ? this->close();
? ? }
}
QByteArray tcp_socket::data_length_data(QByteArray data){
? ? QByteArray send_data;
? ? QDataStream bin_data(&send_data,QIODevice::ReadWrite);
? ? int data_length=data.size();
? ? bin_data<<(int)data_length;
? ? send_data.append(data);
? ? return send_data;
}
QByteArray tcp_server::data_length_data(QByteArray data){
? ? QByteArray send_data;
? ? QDataStream bin_data(&send_data,QIODevice::ReadWrite);
? ? int data_length=data.size();
? ? bin_data<<(int)data_length;
? ? send_data.append(data);
? ? return send_data;
}
```