多线程传输文件Word下载.docx
- 文档编号:19991952
- 上传时间:2023-01-13
- 格式:DOCX
- 页数:11
- 大小:20.22KB
多线程传输文件Word下载.docx
《多线程传输文件Word下载.docx》由会员分享,可在线阅读,更多相关《多线程传输文件Word下载.docx(11页珍藏版)》请在冰豆网上搜索。
char
Name[100];
//文件名称
int
FileLen;
//文件长度
CMD;
//操作指令
seek;
//线程开始位置
SOCKETsockid;
}FILEINFO;
1.请求文件信息
客户端代码如下
FILEINFOfi;
memset((char*)&
fi,0,sizeof(fi));
fi.CMD=1;
//得到文件信息
if(send(client,(char*)&
fi,sizeof(fi),0)==SOCKET_ERROR)
{
cout<
<
"
SendGetFileInfoError\n"
;
}
服务端代码如下
while(true)
SOCKETclient;
if(client=accept(server,(sockaddr*)&
clientaddr,&
len))
FILEINFORecvFileInfo;
RecvFileInfo,0,sizeof(RecvFileInfo));
if(recv(client,(char*)&
RecvFileInfo,sizeof(RecvFileInfo),0)==SOCKET_ERROR)
TheClinetSocketisClosed\n"
break;
}else
EnterCriticalSection(&
CS);
//进入临界区
memcpy((char*)&
TempFileInfo,(char*)&
RecvFileInfo,sizeof(RecvFileInfo));
switch(TempFileInfo.CMD)
case1:
GetInfoProc
(client);
case2:
TempFileInfo.sockid=client;
CreateThread(NULL,NULL,GetFileProc,NULL,NULL,NULL);
LeaveCriticalSection(&
//离开临界区
在这里服务端循环接受连接,并跟据TempFileInfo.CMD来判断客户端的请求类型,1为请求文件信息,2为下载文件
因为在下载文件的请求中,需要开辟新的线程,并传递文件偏移和文件大小等信息,所以需要对线程同步.这里使用临界区
其文件信息函数GetInfoProc代码如下
DWORDGetInfoProc(SOCKETclient)
CFile
file;
if(file.Open(FileName,CFile:
:
modeRead|CFile:
typeBinary))
intFileLen=file.GetLength();
FileLen,sizeof(FileLen),0)==SOCKET_ERROR)
"
SendFileLenError\n"
TheFilelenis"
FileLen<
\n\n"
return0;
}
这里主要是向客户端传递文件长度,而客户端收到长度后则开辟线程进行连接传输文件
2.客户端跟据长度开辟线程
其实现代码如下
FILEINFOFI;
intFileLen=0;
FileLen,sizeof(FileLen),0)==SOCKET_ERROR)//接受文件长度
RecvFileLenError\n"
FileLenis"
\n"
intCOUNT_SIZE=FileLen/5;
//每线程传输大小
for(inti=0;
i<
5;
i++)
//分5个线程传输
FI,0,sizeof(FI));
FI.CMD=2;
//请求下载文件
FI.seek=i*COUNT_SIZE;
//线程文件偏移
if(i+1==5)
//最后一线程长度为总长度减前4个线程长度
FI.FileLen=FileLen-COUNT_SIZE*i;
FI.FileLen=COUNT_SIZE;
Thread=CreateThread(NULL,NULL,GetFileThread,&
i,NULL,NULL);
Sleep(500);
WaitForMultipleObjects(5,Thread,true,INFINITE);
//等所有线程结束
这里默认开辟5个线程传输,当然可以改为想要的线程数目,仍然用临界区来实现线程的同步问题
3.服务端开辟线程传输数据
在1.请求文件信息中以说明了服务端的结构,这里主要介绍线程函数的实现,其代码如下
DWORDWINAPIGetFileProc(LPVOIDlparam)
intFileLen=TempFileInfo.FileLen;
intSeek=TempFileInfo.seek;
SOCKETclient=TempFileInfo.sockid;
file.Seek(Seek,CFile:
begin);
//指针移至偏移位置
char*date=newchar[FileLen];
intnLeft=FileLen;
intidx=0;
file.Read(date,FileLen);
while(nLeft>
0)
intret=send(client,&
date[idx],nLeft,0);
if(ret==SOCKET_ERROR)
SendDateError\n"
nLeft-=ret;
idx+=ret;
file.Close();
delete[]date;
openthefileerror\n"
closesocket(client);
还是比较简单的,主要是获取线程的文件长度和偏移,并移动文件指针到偏移处,最后读取发送数据,而客户端
接受数据并写入文件.
4.客户端将线程数据保存到文件
GetFileThread的实现代码如下
DWORDWINAPIGetFileThread(LPVOIDlparam)
charTempName[MAX_PATH];
sprintf(TempName,"
TempFile%d"
*(DWORD*)lparam);
//每线程的文件名为"
TempName"
+线程数
SOCKADDR_INserveraddr;
intport=5555;
client=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
serveraddr.sin_family=AF_INET;
serveraddr.sin_port=htons(port);
serveraddr.sin_addr.S_un.S_addr=inet_addr("
127.0.0.1"
);
if(connect(client,(SOCKADDR*)&
serveraddr,sizeof(serveraddr))==INVALID_SOCKET)
ConnectServerError\n"
FI,sizeof(FI),0)==SOCKET_ERROR)
SendGetFileError\n"
intFileLen=FI.FileLen;
intSeek=FI.seek;
//文件偏移
if(file.Open(TempName,CFile:
modeWrite|CFile:
typeBinary|CFile:
modeCreate))
char*date=newchar[FileLen];
intret=recv(client,&
RecvDateError"
file.Write(date,FileLen);
CreateFileError\n"
在此线程函数中,将每线程传输的数据存为一个文件,文件名为"
+线程数,只所以存成单独的文件是
因为比较直观且容易理解,但如果文件很大的话这个方法并不好,因为合并文件又会花费很多时间,另一个方法
是创始一个文件,让每个线程写入文件的不同偏移,这样就可以不必单独合并文件了,但要记得打开文件时
加入CFile:
shareDenyNone属性.这样整个过程就完成了.最后一步合并线程文件
5.合并线程文件
intUniteFile()
//合并线程文件
NowisUniteFileing...\n"
len;
*date;
file0;
/*其它文件......*/
modeCreate|CFile:
modeWrite))//创建文件
file0.Open("
TempFile0"
CFile:
typeBinary);
//合并第一线程文件
len=file0.GetLength();
date=newchar[len];
file0.Read(date,len);
file.SeekToEnd();
file.Write(date,len);
file1.Open("
TempFile1"
//合并第二线程文件
len=file1.GetLength();
file1.Read(date,len);
/*合并其它线程......*/
file0.Close();
file1.Close();
/*.......*/
returntrue;
returnfalse;
这个简单,就是打开一个文件读取到缓冲区,写入文件,再打开第二个......现在多线程传输部分就介绍完了
下面讨论断断点续传的实现!
c++实现文件传输之四:
断点传输
收藏
所谓的断点续传就是指:
文件在传输过程式中被中断后,在重新传输时,可以从上次的断点处开始传输,这样就可节省时间,和其它资源.
实现关键在这里有两个关键点,其一是检测本地已经下载的文件长度和断点值,其二是在服务端调整文件指针到断点处
实现方法
我们用一个简单的方法来实现断点续传的功能.在传输文件的时候创建一个临时文件用来存放文件的断点位置
在每次发送接受文件时,先检查有没有临时文件,如果有的话就从临时文件中读取断点值,并把文件指针移动到
断点位置开始传输,这样便可以做到断点续传了
首次传输其流程如下
1.服务端向客户端传递文件名称和文件长度
2.跟据文件长度计算文件块数(文件分块传输请参照第二篇文章)
3.客户端将传输的块数写入临时文件(做为断点值)
4.若文件传输成功则删除临时文件
首次传输失败后将按以下流程进行
1.客户端
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 多线程 传输 文件