欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Qt開發(fā)之使用socket實(shí)現(xiàn)遠(yuǎn)程控制

 更新時(shí)間:2022年11月19日 09:52:37   作者:音視頻開發(fā)老舅  
本篇文章將會(huì)介紹下位機(jī)通過(guò)心跳包和上位機(jī)之間進(jìn)行數(shù)據(jù)交互和遠(yuǎn)程功能控制的實(shí)現(xiàn)方法。文中的示例代碼講解詳細(xì),感興趣的可以了解一下

Qt之使用socket實(shí)現(xiàn)遠(yuǎn)程控制

在前面的文章中介紹過(guò)Qt心跳包的實(shí)現(xiàn)方法,本篇文章將會(huì)介紹下位機(jī)通過(guò)心跳包和上位機(jī)之間進(jìn)行數(shù)據(jù)交互和遠(yuǎn)程功能控制的實(shí)現(xiàn)方法。

首先介紹環(huán)境,下位機(jī)使用Qt作為主程序,上下位機(jī)使用TCP socket進(jìn)行網(wǎng)絡(luò)通信,上位機(jī)實(shí)現(xiàn)方式任意。下位機(jī)心跳包線程在進(jìn)程一開始就啟動(dòng),一直到進(jìn)程結(jié)束才停止。

心跳包是一個(gè)始終獨(dú)立的線程,首先要搭建框架:

main.cpp

#include <heartbeatthread.h>
 
    //心跳包線程
    heartbeatThread *ht = nullptr;
    ht = new heartbeatThread;
    ht -> start();

.h文件

#ifndef HEARTBEATTHREAD_H
#define HEARTBEATTHREAD_H
 
#include <QThread>
#include <QCoreApplication>
#include <QTimer>
#include <QTcpSocket>
#include <QHostAddress>
#include <QtConcurrent/QtConcurrent>
 
using namespace std;
 
class heartbeatThread : public QThread
{
    Q_OBJECT
 
public:
    explicit heartbeatThread(QObject *parent = nullptr);
    void run(); //任務(wù)處理線程
 
    ~heartbeatThread(){
    }
 
public slots:
 
private:
    QTcpSocket *tcpSocket = nullptr;
 
protected:
};
 
#endif // HEARTBEATTHREAD_H

.cpp文件

#include "heartbeatthread.h"
 
heartbeatThread::heartbeatThread(QObject *parent)
{
}
 
void heartbeatThread::run()
{
    tcpSocket = new QTcpSocket();
    tcpSocket->connectToHost(QHostAddress("127.0.0.1"), 5000);
 
    QtConcurrent::run([=]()
        {
        while(true)
        {
            try{    //收包
                //將接收內(nèi)容存儲(chǔ)到字符串中
                char recvMsg[1024] = {'\0'};
                int recvRe = tcpSocket->read(recvMsg, 1024);
                if(recvRe != 0 && recvRe != -1) //0:連接未發(fā)信息;-1:未連接
                {
                }
            } catch(...){}
            QEventLoop eventloop;
            QTimer::singleShot(1, &eventloop, SLOT(quit()));
            eventloop.exec();
        }
    });
 
    while(true){
        try{    //發(fā)包
            //等待連接成功
            if(!tcpSocket->waitForConnected(30000))
            {
                tcpSocket->connectToHost(QHostAddress("127.0.0.1"), 5000);
            }
            else
            {                
                QByteArray block = "block";
                tcpSocket->write(block);
                tcpSocket->flush();
            }
        } catch(...){}
        QEventLoop eventloop;
        QTimer::singleShot(1000, &eventloop, SLOT(quit()));
        eventloop.exec();
    }
}

這樣收發(fā)就寫好了。

先說(shuō)發(fā)包,這里是和上位機(jī)建立了長(zhǎng)連接,我只需要知道上位機(jī)的IP和端口號(hào)即可建立連接,上位機(jī)不需要知道我的IP信息。如果上位機(jī)需要知道我的相關(guān)信息,可以在包中寫入,并根據(jù)實(shí)際需要調(diào)整發(fā)送頻率。這里有重連機(jī)制,上位機(jī)在一段時(shí)間沒有收到我發(fā)送的信息后,可以認(rèn)定我已經(jīng)離線。

再說(shuō)收包,其實(shí)就是不斷地讀入緩沖區(qū)的內(nèi)容,緩沖區(qū)的大小和解析方式需要和上位機(jī)協(xié)調(diào),盡量在包過(guò)大時(shí)進(jìn)行拆包發(fā)送,下位機(jī)再根據(jù)解包信息判斷是否需要接包,以及信息是否齊全、有沒有丟包等。

收發(fā)框架搭好以后,就可以建立一定的收發(fā)規(guī)范進(jìn)行遠(yuǎn)程控制了,發(fā)包比較靈活,這里只說(shuō)收包。

比如設(shè)定這樣的規(guī)則:上位機(jī)發(fā)送的所有的報(bào)文都有一段報(bào)文頭,記錄報(bào)文的總長(zhǎng)度。報(bào)文頭部后面接一段自定義的操作類型,用來(lái)進(jìn)行指令分類。操作類型后接實(shí)際的操作指令。

代碼如下。

try{    //收包
    //將接收內(nèi)容存儲(chǔ)到字符串中
    char recvMsg[1024] = {'\0'};
    int recvRe = tcpSocket->read(recvMsg, 1024);
    if(recvRe != 0 && recvRe != -1) //0:連接未發(fā)信息;-1:未連接
    {
        QString recvMessage = recvMsg;
        //字符串解析
        head = recvMessage.mid(0, HEAD_LENGTH).simplified();  //網(wǎng)絡(luò)頭,報(bào)文總長(zhǎng)度
        type = recvMessage.mid(HEAD_LENGTH, TYPE_LENGTH).simplified();  //請(qǐng)求類型
        message = recvMessage.mid(HEAD_LENGTH + TYPE_LENGTH, recvMessage.length()).simplified();  //實(shí)際請(qǐng)求內(nèi)容
        //按照字符串要求分類處理
        handle(type, message);
    }
} catch(...){}

預(yù)先定好報(bào)文頭部和指令類型的長(zhǎng)度,就可以在收到包后按照位置對(duì)字符串進(jìn)行解析。分離出請(qǐng)求類型和請(qǐng)求內(nèi)容后,對(duì)指令進(jìn)行處理即可。同時(shí)也需要定義一定的上位機(jī)指令發(fā)送規(guī)范。

處理示例:

void handle(QString type, QString message)
{
    QStringList handleOptions;
    handleOptions << "aaaa" << "bbbb" << "cccc" ;
 
    /*
    aaaa = 0
    bbbb = 1
    cccc = 2
    */
 
    switch (handleOptions.indexOf(type)) {
    case 0:
        break;
    case 1:
        break;
    case 2:
        break;
   default:
        qDebug() << "do not understand!";
        break;
    }
}
 

到此這篇關(guān)于Qt開發(fā)之使用socket實(shí)現(xiàn)遠(yuǎn)程控制的文章就介紹到這了,更多相關(guān)Qt socket遠(yuǎn)程控制內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++形參與實(shí)參的區(qū)別實(shí)例解析

    C++形參與實(shí)參的區(qū)別實(shí)例解析

    這篇文章主要介紹了C++形參與實(shí)參的區(qū)別實(shí)例解析,需要的朋友可以參考下
    2014-07-07
  • C語(yǔ)言使用單鏈表實(shí)現(xiàn)學(xué)生信息管理系統(tǒng)

    C語(yǔ)言使用單鏈表實(shí)現(xiàn)學(xué)生信息管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言使用單鏈表實(shí)現(xiàn)學(xué)生信息管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • C++使用函數(shù)的一些高級(jí)操作指南

    C++使用函數(shù)的一些高級(jí)操作指南

    C++中函數(shù)調(diào)用的方法與C語(yǔ)言并無(wú)區(qū)別,依舊是在調(diào)用方函數(shù)中執(zhí)行函數(shù)調(diào)用語(yǔ)句來(lái)實(shí)現(xiàn)函數(shù)調(diào)用,下面這篇文章主要給大家介紹了關(guān)于C++使用函數(shù)的一些高級(jí)操作,文中通過(guò)圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2022-12-12
  • C語(yǔ)言中fchdir()函數(shù)和rewinddir()函數(shù)的使用詳解

    C語(yǔ)言中fchdir()函數(shù)和rewinddir()函數(shù)的使用詳解

    這篇文章主要介紹了C語(yǔ)言中fchdir()函數(shù)和rewinddir()函數(shù)的使用詳解,是C語(yǔ)言入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2015-09-09
  • C++中箭頭運(yùn)算符的含義與用法講解

    C++中箭頭運(yùn)算符的含義與用法講解

    今天小編就為大家分享一篇關(guān)于C++中箭頭運(yùn)算符的含義與用法講解,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2019-04-04
  • Objective-C中常用的結(jié)構(gòu)體NSRange,NSPoint,NSSize(CGSize),NSRect實(shí)例分析

    Objective-C中常用的結(jié)構(gòu)體NSRange,NSPoint,NSSize(CGSize),NSRect實(shí)例分析

    這篇文章主要介紹了Objective-C中常用的結(jié)構(gòu)體NSRange,NSPoint,NSSize(CGSize),NSRect實(shí)例分析,有助于更加直觀的理解Object-C常用的結(jié)構(gòu)體,需要的朋友可以參考下
    2014-07-07
  • 詳解C語(yǔ)言的mem系列函數(shù)

    詳解C語(yǔ)言的mem系列函數(shù)

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言的mem系列函數(shù),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2022-02-02
  • C++表達(dá)式new與delete知識(shí)詳解

    C++表達(dá)式new與delete知識(shí)詳解

    這篇文章主要為大家詳細(xì)介紹了C++表達(dá)式new與delete知識(shí)點(diǎn),學(xué)習(xí)如何動(dòng)態(tài)創(chuàng)建對(duì)象,動(dòng)態(tài)創(chuàng)建的對(duì)象與一般對(duì)象的區(qū)別,動(dòng)態(tài)創(chuàng)建的對(duì)象的初始化以及釋放動(dòng)態(tài)分配的內(nèi)存等知識(shí)點(diǎn),感興趣的朋友可以參考一下
    2016-05-05
  • C++11 模板參數(shù)的“右值引用”是轉(zhuǎn)發(fā)引用嗎

    C++11 模板參數(shù)的“右值引用”是轉(zhuǎn)發(fā)引用嗎

    這篇文章主要介紹了C++11 模板參數(shù)的“右值引用”是轉(zhuǎn)發(fā)引用嗎,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-05-05
  • C++中const與#define的利弊分析

    C++中const與#define的利弊分析

    C++中不但可以用define定義常量還可以用const定義常量,下面這篇文章主要給大家分析介紹了關(guān)于C++中const與#define的利弊,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2018-05-05

最新評(píng)論