文档介绍:继木马编程DIY的上两篇,
必不可少的功能了,,首先向网络蚂蚁的作者
洪以容前辈致敬,
,我们将断点续传与多线程传输分别用两个程序来实现
多线程传输实现
实现原理
将源文件按长度为分为N块文件,然后开辟N个线程,每个线程传输一块,
-100M,第二线程从100M-200M......最后合并5个线程文件.
实现流程
客户端向服务端请求文件信息(名称,长度)
客户端跟据文件长度开辟N个线程连接服务端
服务端开辟新的线程与客户端通信并传输文件
客户端将每线程数据保存到一个文件
合并所有线程文件
编码实现
大体说来就是按以上步骤进行,详细的实现和一些要点,我们跟据以上流程在编码中实现
结构定义
在通信过程中需要传递的信息包括文件名称,文件长度,文件偏移,操作指令等信息,为了方便操作我们定义如下结构typedef struct
{
char Name[100]; //文件名称
int FileLen; //文件长度
int CMD; //操作指令
int seek; //线程开始位置
SOCKET sockid;
}FILEINFO;
客户端代码如下FILEINFO fi;
memset((char*)&fi,0,sizeof(fi));
=1; //得到文件信息
if(send(client,(char*)&fi,sizeof(fi),0)==SOCKET_ERROR)
{
cout<<"Send Get FileInfo Error\n";
}
服务端代码如下
while(true)
{
SOCKET client;
if(client=accept(server,(sockaddr *)&clientaddr,&len))
{
FILEINFO RecvFileInfo;
memset((char*)&RecvFileInfo,0,sizeof(RecvFileInfo));
if(recv(client,(char*)&RecvFileInfo,sizeof(RecvFileInfo),0)==SOCKET_ERROR)
{
cout<<"The Socket is Closed\n";
break;
}else
{
EnterCriticalSection(&CS); //进入临界区
memcpy((char*)&TempFileInfo,(char*)&RecvFileInfo,sizeof(RecvFileInfo));
switch()
{
case 1:
GetInfoProc (client);
break;
case 2:
=client;
CreateThread(NULL,NULL,GetFileProc,NULL,NULL,NULL);
break;
}
LeaveCriticalSection(&CS); //离开临界区
}
}
}
复制代码在这里服务端循环接受连接,,1为请求文件信息,2为下载文件
因为在下载文件的请求中,需要开辟新的线程,并传递文件偏移和文件大小等信息,
其文件信息函数GetInfoProc代码如下DWORD GetInfoProc(SOCKET client)
{
CFile file;
if((FileName,CFile::modeRead|CFile::typeBinary))
{
int FileLen=();
if(send(client,(char*)&FileLen,sizeof(FileLen),0)==SOCKET_ERROR)
{
cout<< "Send FileLen Error\n";
}else
{
cout<< "The Filelen is "<<FileLen<<"\n\n";
}
}
return 0;
}
复制代码这里主要是向客户端传递文件长度,而客户端收到长度后则开辟线程进行连接传输文件
客户端跟据