您的位置:首页 > 编程语言 > Qt开发

最新基于Qt实现多电脑屏幕监控

2017-12-27 14:03 435 查看
本项目的原理是,多客户端通过后台的不断截屏,通过TCP socket 发送到服务器端进行项目,目前我代码里面设置最大监控4台电脑,当然你也可以自己设置哈。

客户端代码

//头文件tcpimageclient.h

#ifndef TCPIMAGECLIENT_H
#define TCPIMAGECLIENT_H
#include<QObject>
#include<QTcpSocket>
#include<QTimer>

class TcpImageClient:public QObject
{
Q_OBJECT
public:
TcpImageClient(QString ipAddr,QObject* parent=0);
~TcpImageClient();
void sendImageData(QByteArray imageData);
public:signals:
void connectSuccess();
void distConnect();
private slots:
void connectHost();
private:
QTcpSocket *m_socket;
QString _ipAddress;

QTimer* time;
};

#endif // TCPIMAGECLIENT_H

//tcpimageclient.cpp

#include"tcpimageclient.h"
#include<QDebug>

TcpImageClient::TcpImageClient(QString ipAddr,QObject *parent):QObject(parent)
{
_ipAddress = ipAddr;
m_socket = new QTcpSocket(this);
time = new QTimer(this);
m_socket->abort();
connect(m_socket,SIGNAL(connected()),time,SLOT(stop()));
connect(m_socket,SIGNAL(connected()),this,SIGNAL(connectSuccess()));
connect(m_socket,SIGNAL(disconnected()),this,SIGNAL(distConnect()));
connect(time,SIGNAL(timeout()),this,SLOT(connectHost()));
time->start(200);
}

TcpImageClient::~TcpImageClient()
{

}

void TcpImageClient::sendImageData(QByteArray imageData)
{
//    qDebug()<<imageData.size();
m_socket->write(imageData);

}

void TcpImageClient::connectHost()
{
if(m_socket->state() == QAbstractSocket::ConnectingState)
return;
m_socket->connectToHost(_ipAddress,19999);
}

//实现很简单,就没有什么注释了

//desktopclient.h

#ifndef DESKTOPCLIENT_H
#define DESKTOPCLIENT_H

#include <QWidget>
#include<QPixmap>
#include"tcpimageclient.h"
#include<QScreen>
#include<QTimer>
#include<QSystemTrayIcon>
#include<QMenu>
#include<QAction>

namespace Ui {
class DeskTopClient;
}

class DeskTopClient : public QWidget
{
Q_OBJECT

public:
explicit DeskTopClient(QWidget *parent = 0);
~DeskTopClient();

private slots:
void SendCutImageData();
void HandleClose();
private:
Ui::DeskTopClient *ui;
TcpImageClient *m_client;
QScreen *screen;
QTimer * time;

QSystemTrayIcon *m_trayIcon;
QMenu *mMenu;
QAction *exitAction;
QString _ipAddr;
int _machineId;
int _frame;

void ReadConfig();

};

#endif // DESKTOPCLIENT_H

//desktopclient.cpp

#include "desktopclient.h"
#include "ui_desktopclient.h"
#include<QMessageBox>
#include<QPixmap>
#include<QDebug>
#include<QBuffer>
#include<QDataStream>
#include<QByteArray>
#include<QIODevice>
#include<QSettings>

DeskTopClient::DeskTopClient(QWidget *parent) :
QWidget(parent),
ui(new Ui::DeskTopClient)
{
ui->setupUi(this);

this->setWindowFlags(Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint | Qt::ToolTip);
m_trayIcon = new QSystemTrayIcon(this);
m_trayIcon->setIcon(QIcon(":/view.ico"));     //设置图标
mMenu = new QMenu(this);
exitAction = new QAction(QStringLiteral("Exit"),this);
mMenu->addAction(exitAction);
m_trayIcon->setContextMenu(mMenu);
connect(exitAction,SIGNAL(triggered(bool)),this,SLOT(HandleClose()));
m_trayIcon->show();
m_trayIcon->showMessage("tip","desktopclient has started",QSystemTrayIcon::Information,1000);
ReadConfig();

screen = QGuiApplication::primaryScreen();
m_client = new TcpImageClient(_ipAddr);
time = new QTimer(this);
time->setInterval(1000/_frame);
connect(time,SIGNAL(timeout()),this,SLOT(SendCutImageData()));
connect(m_client,SIGNAL(connectSuccess()),time,SLOT(start()));
connect(m_client,SIGNAL(distConnect()),time,SLOT(stop()));
}

DeskTopClient::~DeskTopClient()
{
delete m_client;
delete ui;
}

void DeskTopClient::SendCutImageData()
{
QPixmap image =  screen->grabWindow(0);//抓屏
QBuffer buffer;
image.save(&buffer,"PNG");
quint32 len = buffer.data().size() + 8;//设置发送数据的长度
QByteArray dataArray;
QDataStream stream(&dataArray,QIODevice::WriteOnly);
stream << len;//数据长度
stream << _machineId;//电脑ID
dataArray.append(buffer.data());
m_client->sendImageData(dataArray);

}

void DeskTopClient::HandleClose()
{
QApplication::quit();
}

void DeskTopClient::ReadConfig()
{
QSettings settings("config.ini",QSettings::IniFormat);
settings.beginGroup("config");
if(settings.value("ipAddr").toString().isEmpty()){
QMessageBox box;
box.setWindowTitle("ip地址错误");
box.setText("请先配置服务端IP地址,再打开");
box.exec();
HandleClose();
return;
}
_ipAddr = settings.value("ipAddr").toString();

if(settings.value("machineId").toString().isEmpty()){
QMessageBox box;
box.setWindowTitle("ip地址错误");
box.setText("请先配置机器ID,再打开");
box.exec();
HandleClose();
return;
}
_machineId = settings.value("machineId").toInt();

if(settings.value("frame").toString().isEmpty()){
QMessageBox box;
box.setWindowTitle("ip地址错误");
box.setText("请先配置帧率,再打开");
box.exec();
HandleClose();
return;
}

_frame = settings.value("frame").toInt();
settings.endGroup();

}


服务端

//tcpimageserver.h

#ifndef TCPIMAGESERVER_H
#define TCPIMAGESERVER_H
#include<QTcpServer>
#include<QTcpSocket>
#include<QObject>
#include<QMap>

class TcpImageServer:public QObject
{
Q_OBJECT
public:
TcpImageServer(QObject* parent=0);
~TcpImageServer();
public:signals:
void recvImage(QByteArray imageData,int index);

private slots:
void newConnect();
void readMessage();
void removeClient();
private:
QTcpServer *m_server;
QMap<QString,QTcpSocket*>m_mapClient;
QMap<QTcpSocket*,QByteArray>m_recvData;

void xmlData();
};

#endif // TCPIMAGESERVER_H

//tcpimageserver.cpp

#include"tcpimageserver.h"
#include<QHostAddress>
#include<QDataStream>
#include<QBuffer>
#include<QDebug>

TcpImageServer::TcpImageServer(QObject* parent):QObject(parent)
{
m_server = new QTcpServer(this);
m_server->setMaxPendingConnections(4);//这里是我设置最大接入数是4
m_server->listen(QHostAddress::Any,19999);
connect(m_server,SIGNAL(newConnection()),this,SLOT(newConnect()));
}

TcpImageServer::~TcpImageServer()
{

}

void TcpImageServer::newConnect()
{
QTcpSocket * m_socket = m_server->nextPendingConnection();
connect(m_socket,SIGNAL(readyRead()),this,SLOT(readMessage()));
m_mapClient.insert(m_socket->peerAddress().toString(),m_socket);
connect(m_socket,SIGNAL(disconnected()),this,SLOT(removeClient()));

}

void TcpImageServer::readMessage()
{
QTcpSocket *m_socket = reinterpret_cast<QTcpSocket*>(sender());
QByteArray dataArray =  m_socket->readAll();
if(m_recvData.contains(m_socket))
m_recvData[m_socket].append(dataArray);   //由于图片数据过大,会存在多包发送,因此先用容器存储在解析
else
m_recvData[m_socket] = dataArray;
xmlData();
}

void TcpImageServer::xmlData()//解析一张图片数据
{
QMap<QTcpSocket*,QByteArray>::iterator it;

for(it = m_recvData.begin();it!=m_recvData.end();it++)
{
if(it.value().size() == 0)
continue;

int size = 0;
int machineId = 1;
QDataStream stream(& it.value(),QIODevice::ReadOnly);
stream >> size;
stream >> machineId;
if(size <= it.value().size()){
QByteArray imageData = it.value().mid(8,size);
it.value() = it.value().mid(size);
emit recvImage(imageData,machineId);
}

}
}

void TcpImageServer::removeClient()
{
QTcpSocket* socket = reinterpret_cast<QTcpSocket*>(sender());

QMap<QString, QTcpSocket *>::iterator it;

for(it=m_mapClient.begin();it!=m_mapClient.end();it++)
{
if(socket->peerAddress().toString() == it.key())
{
m_mapClient.erase(it);
break;
}
}

}


完整代码 :点击下载
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: