当前位置: 首页 > article >正文

libvncclient编写多线程qt的VNC客户端

概述

  • 使用qt和libvncclient编写vnc的客户端程序,多线程读写,拒绝卡顿。
  • qt环境:5.15.3
  • libvncclient:0.9.14
  • 下载地址:https://github.com/LibVNC/libvncserver/releases

编译libvncclient

  • 打开CMakeList文件,找到编译开关,注释掉不需要的编译项目:
# all the build configuration switches
option(LIBVNCSERVER_INSTALL "Generate installation target" ON)
option(BUILD_SHARED_LIBS "Build shared libraries" ${UNIX})
option(WITH_ZLIB "Search for the zlib compression library to support additional encodings" ON)
option(WITH_LZO "Search for the LZO compression library to omit internal miniLZO implementation" ON)
option(WITH_JPEG "Search for the libjpeg compression library to support additional encodings" ON)
option(WITH_PNG "Search for the PNG compression library to support additional encodings" ON)
option(WITH_SDL "Search for the Simple Direct Media Layer library to build an example SDL vnc client" ON)
option(WITH_GTK "Search for the GTK library to build an example GTK vnc client" ON)
option(WITH_LIBSSHTUNNEL "Search for libsshtunnel to build an example ssh-tunneled client" ON)
option(WITH_THREADS "Search for a threading library to build with multithreading support" ON)
option(PREFER_WIN32THREADS "When searching for a threading library, prefer win32 threads if they are found" ON)
option(WITH_GNUTLS "Search for the GnuTLS secure communications library to support TLS" OFF)
option(WITH_OPENSSL "Search for the OpenSSL cryptography library to support TLS and use as crypto backend" ON)
option(WITH_SYSTEMD "Search for libsystemd to build with systemd socket activation support" ON)
option(WITH_GCRYPT "Search for Libgcrypt to use as crypto backend" ON)
option(WITH_FFMPEG "Search for FFMPEG to build an example VNC to MPEG encoder" ON)
option(WITH_TIGHTVNC_FILETRANSFER "Enable filetransfer if there is pthreads support" ON)
option(WITH_24BPP "Allow 24 bpp" ON)
option(WITH_IPv6 "Enable IPv6 Support" ON)
option(WITH_WEBSOCKETS "Build with websockets support" ON)
option(WITH_SASL "Build with SASL support" ON)
option(WITH_XCB "Build with XCB support" ON)
option(WITH_EXAMPLES "Build examples" OFF)
option(WITH_TESTS "Build tests" OFF)
option(WITH_QT "Build the Qt client example" OFF)
  • 也可以自己手动去掉不需要的库依赖,我这里没有把server的库依赖去干净。
  • 然后取出项目中的libvncclient.so和头文件中的client目录到自己的项目中。
  • 将build目录中的include中的rfbconfig.h拷贝到头文件目录

项目思路

  • 主要思路如下:
  • 创建一个主窗口QWidget用于画面渲染,创建一个接收线程和一个发送线程。
  • 接收线程负责读取vnc服务器发送的数据并解码装换成QImage,通过信号发送QImage,通知主线程刷新页面。
  • 发送线程用于发送主窗口的鼠标移动,点击等事件,用于实时更新操作。

项目编写

  • VncWideget : 主要的渲染窗口
#ifndef VNCVIEWWIDGET_H
#define VNCVIEWWIDGET_H

#include <QWidget>
#include <QThread>

#include "rfb/rfbclient.h"
#include "rfb/rfbconfig.h"

#include "vnc_client/vncrecvthread.h"
#include "vnc_client/vncsendworker.h"

class VncViewWidget : public QWidget
{
    Q_OBJECT
public:
    explicit VncViewWidget(QString ip, quint32 port, QWidget *parent = nullptr);
    ~VncViewWidget();

    void start();
    void stop();
    inline bool isStarted(){
        return _startFlag;
    }

    void updateImage(const QImage& image);

    void paintEvent(QPaintEvent *event) override;
    void mouseMoveEvent(QMouseEvent* event) override;
    void mousePressEvent(QMouseEvent *event) override;
    void mouseReleaseEvent(QMouseEvent *event) override;
    void closeEvent(QCloseEvent* event) override;

private:
    QImage _image;
    rfbClient *_cl;
    QString _ip;
    quint32 _port;
    bool _startFlag = false;

    QThread* _vncSendThread;
    VNCSendWorker* _vncSendWorker;
    VNCRecvThread* _vncRecvThread;

signals:
    void sendMouseState(rfbClient* cl, int x, int y, int button);
    void fullWindowCloseSignal();

public slots:
};

#endif // VNCVIEWWIDGET_H

  • VNCSendWorker:数据发送工作线程
#ifndef VNCSENDWORKER_H
#define VNCSENDWORKER_H

#include <QObject>

#include "rfb/rfbclient.h"

class VNCSendWorker : public QObject
{
    Q_OBJECT
public:
    explicit VNCSendWorker( QObject *parent = nullptr);

signals:

public slots:
    void sendMouseUpdateMsg(rfbClient* cl, int x, int y, int button);

};

#endif // VNCSENDWORKER_H

VNCRecvThread :接收线程

#ifndef VNCRECVTHREAD_H
#define VNCRECVTHREAD_H

#include <QThread>

#include <QImage>

#include "rfb/rfbclient.h"

class VNCRecvThread : public QThread
{
    Q_OBJECT
public:
    VNCRecvThread(QObject* parent = nullptr);

    inline void startRun(rfbClient* cl){
        if(_runFlag)return;
        _cl = cl;
        _cl->FinishedFrameBufferUpdate = frameBufferUpdated;
        rfbClientSetClientData(_cl, nullptr, this);
        _runFlag = true;
        this->start();
    }

    inline void stopRun(){
        if(!_runFlag)return;
        _runFlag = false;
        if(_cl)rfbClientSetClientData(_cl, nullptr, nullptr);
        if(_cl)_cl->FinishedFrameBufferUpdate = nullptr;
        _cl = nullptr;
    }

    static void frameBufferUpdated(rfbClient* cl);

protected:
    void run() override;

private:
    bool _runFlag = false;
    rfbClient* _cl;

signals:
    void updateImageSignal(QImage);
};

#endif // VNCRECVTHREAD_H

项目完整代码

gitee:https://gitee.com/li-gouhi2333/vncclient/tree/master/


http://www.kler.cn/a/293758.html

相关文章:

  • XSS安全基础
  • RS®SZM 倍频器
  • 操作系统离散存储练习题
  • aws(学习笔记第十二课) 使用AWS的RDS-MySQL
  • Linux手动安装nginx
  • 给查询业务添加redis缓存和缓存更新策略
  • Spring Boot 注解探秘:HTTP 请求的魅力之旅
  • docker里修改时间为上海时间
  • 【python】—— Python爬虫实战:爬取珠海市2011-2023年天气数据并保存为CSV文件
  • 保研 比赛 利器: 用AI比赛助手降维打击数学建模
  • SpringMVC基于注解使用:JSON
  • 端口安全老化细节
  • Sentence-BERT实现文本匹配【分类目标函数】
  • Gitlab-ce upgrade 16.0.1 to 17.3.1【Gitlab-ce 16.0.1 升级 17.3.1】
  • git 提交代码由原先账号密码调整为ssh
  • DevExpress WinForms v24.1新版亮点:功能区、数据编辑器全新升级
  • xxl-job分布式任务调度平台
  • 「深入理解」HTML Meta标签:网页元信息的配置
  • 在嵌入式板子上搭建和自定义live555服务器---编译问题和方法整理
  • 虚幻5|C++第三人称射击(1)添加摄像机
  • 球球大作战
  • ELK学习笔记(二)——使用K8S部署Kibana8.15.0
  • 辨别高防服务器
  • python tkinter 文本类组件
  • python 下载excel 添加水印
  • [240907] Python 标准库中鲜为人知的宝藏 | Node.js 22.8.0 发布:编译缓存 API、覆盖率阈值等新特性