下载工具的设计与开发.docx
《下载工具的设计与开发.docx》由会员分享,可在线阅读,更多相关《下载工具的设计与开发.docx(54页珍藏版)》请在冰豆网上搜索。
下载工具的设计与开发
下载工具的设计与开发
摘要
在BT软件以及电驴等P2P工具日益发展的今天,不管你有多少带宽他都会100%的占用。
这类P2P软件的下载速度完全依赖带宽,然而,如何在不提高带宽的前提下提高局域网的下载速度是一个符合实际的问题,本文就基于该问题提出并实现了“分布式下载工具”系统。
该系统很好的解决了局域网被限速的问题,大大提高了下载速度。
“分布式下载工具”联合局域网内的几台客户机同时去下载Internet网上的同一资源的不同数据块,下载完后按顺序统一整合。
它有下载客户机与服务器的功能,分别运用VC和VB.Net开发设计。
客户机完成下载与连接其他用户的功能;而服务器则管理用户和资源情况,供客户机提供在线用户的数据,并且服务器能够对用户和资源进行控制。
比如:
封锁某些不合法的资源、禁止某些不合法的用户使用等。
本系统设计完成后,并与其他下载软件进行了测试比较,提升效果明显,有一定推广使用价值。
关键词:
下载速度;下载软件;局域网
TheDevelopmentofDistributedDownloadTool
ABSTRACT
P2PdownloadtoolslikeBTande-Mulebecameincreasinglydevelopednowadays.Nomatterhowmuchbandwidthyouhave,100percentfullyofitwillbetheoccupied.Downloadspeedofsuchp2psoftwareistotallydependsonthebandwidth.However,howtoboostspeedofLANontheactualityofbandwidthisapracticalissue.thisarticleexpatiatesfromsuchissueandactualize“distributeddownloadtool”system.ThissystemhasaverygoodsolutiontothelimitedLAN,stronglyimprovingthedownloadspeed.
The"Distributeddownloadtool”,isatechnologytojoinseveralclientsatthesametimetodownloaddifferentdatablocksfromthesomeresourcesontheInternet,andeachclientreunifiestheseblocksacompletedfile.Thesystemcanactasclientandserverboth,respectively,withVCandVB.Nettoexploitanddesign.Asaclientitdoesdownloadworkandconnectswithotherusers;whilebeingtheserver,itmanagestheusersandresourcesfortheclientandprovidesonlinedata.Besides,theservercancontrolusersandresources.
Comparedwithotherdownloadsoftware,acompleted“Distributeddownloadtool”systemupgradesdownloadspeedsignificantlyandisofgoodpopularizationvalue.
Keywords:
DownloadSpeeds;DownloadSoftware;LocalAreaNetworks
第一章前言
1.1项目简单介绍
本下载工具是联合局域网内的几台客户机同时去下载Internet网上的同一资源的不同数据块,下载完后按顺序统一整合。
它由下载客户机与服务器两个部分组成,其中客户机完成下载与连接其他用户的功能;而服务器则管理用户和资源情况,供客户机提供在线用户的数据,并且服务器能够对用户和资源进行控制。
比如:
封锁某些不合法的资源、禁止某些不合法的用户使用等。
其原理是利用局域网内高的传输速度和解决局域网被限速问题。
例如:
局域网的主机A要去下载Internet上某服务器的资源,那么它就会联合局域网内的几台主机(主机B,主机C,主机D等),它先请求服务器获取信息(资源大小),然后根据资源大小和联合的主机数平均分配任务,分别向服务器下载数据。
在下载过程中,每台机将定时发送本机所下载的资源给主机A,直到下载完成。
在下载过程中,如果主机C的平均速度与其他主机的平均下载速度相差悬殊的话,那么主机A将发出撤销主机C的请求,然后主机A重新搜索局域网内的其他主机代替主机C。
若局域网内的主机都不能接受请求的话,那主机A将把主机C剩下的资源重新平均分配给正在下载的主机,这样就完成了整个下载任务,因此得到了很短的下载时间。
1.2项目特点
1.本系统实现了多台机的联机下载。
2.本系统能够对机器的性能进行分析,然后调整每台机的下载量。
3.本系统能够检测客户端机器突然死机或者关闭的情况,对其释放,然后重新寻找新的客户端进行下载剩下的资源。
4.本系统能够对每个资源进行管理,当有遇到一些不合法的资源时,可对其资源进行封闭。
5.本系统能够有效管理客户端的使用,当有客户进行一些非法资源的传播时,可对他进行封锁。
1.3项目开发背景
随着网络的发展以及各种应用软件的出现,我们可以通过网络实现与远方亲人进行电话聊天,与朋友进行互动游戏。
因此相应的网络带宽也越来越受到人们的重视,人们一般通过租用更多的带宽来提高网络速度。
但是在BT软件以及电驴等P2P工具日益发展的今天,不管你有多少带宽他都会100%的占用。
所以目前,如何封锁P2P软件逐渐成为局域网网络管理员头疼的问题,很多局域网都将这个问题转换为带宽限制,他们通过一些软件和路由的控制有效地限制了网络带宽,从而实现对P2P软件的控制,大大影响了P2P下载软件的下载速度,效果非常显著。
但是我们总是追求更高品质的网络生活,希望下载速度能够“再快一点”。
对此,我将根据这些存在的问题设计出了此系统,大大提高了下载速度。
1.4项目的创新性
1.本软件能够主动连接其他机器分块进行下载,从而不会出现下载重复资源的现象,而其他P2P软件则是被动的,避免不了下载重复资源。
2.本软件能够有效达到了资源共享,充分利用了局域网内高的传输速度的特点,达到了资源的高效利用。
1.5项目开发的总目标
系统开发的总目标是:
充分利用局域网内的高速的传输速率与解决局域网内被限速带来的下载速度慢的问题来提高他们的下载速度。
第二章需求分析
2.1功能需求
根据校园网特点和目前的下载工具状况,我对这个系统的需求具有以下几个主要功能:
1.单机下载因特网上的资源。
2.连接局域网内的其他用户一起下载因特网上的资源。
3.当遇到本局域网内有其他用户曾下载过的资源,系统能够识别它,然后直接从本局域网下载此资源。
针对以上几个主要功能,可把本系统分为两大模块:
分布式下载工具客户端和分布式下载工具服务器端。
其中分布式下载工具客户端又可分为发起下载管理模块和接受下载管理模块。
2.2性能需求
本系统是利用局域网内每台机互传的速度快的原理,并且是为了解决局域网内被限速导致下载速度慢的问题,所以本系统在一个局域网内并且该局域网内的IP被限了速度的环境下使用时,效果将会达到相当明显。
2.3系统数据流图
2.3.1系统总体数据流图
图2.1系统总体数据流图
从图2.1系统总体数据流图可看出,客户端新建下载任务首先向服务器端发送命令,等待服务器端返回的可供联机的地址,然后客户端根据这些地址向客户端发送联机请求,等待客户端回应,最后一起参与下载。
2.3.2服务器端数据流图
图2.2服务器端顶层数据流图
由上图可看出,客户端发送命令到服务器端,服务器端接收命令,然后对命令的一次处理,处理完后把相应的数据存入数据库,然后再从数据库取出数据,然后把数据经过一次命令处理后把他转为命令,最后把命令发送给客户端。
图2.3系统第二层数据流图
服务器端第二层数据流图如上图所示,命令在处理之后分为6种不同处理过程,系统分别对不同的处理过程来操作数据库,并把所得的结果经过命令格式化转变为命令,最后发送给客户端。
2.3.3客户端数据流图
图2.4客户端顶层数据流图
由图2.4可看出客户端下载任务时,向服务器端发出请求,获取可供联机的用户,然后进行联机区下载。
图2.5客户端第二层数据流图
由图2.5可看出,客户端与服务器,客户端与客户端之间都分别进行命令分析,对不同的命令进行相应的操作。
第三章概要设计
3.1系统结构设计
3.1.1系统结构示意图
图3.1系统结构示意图
3.1.2系统组织模块结构图
图3.2系统组织模块结构图
3.1.3系统HIPO表
(a)发起下载管理模块IPO表
(b)接收下载管理模块IPO表
(C)服务器管理模块
图3.3系统HIPO表
3.2接口设计
3.2.1用户界面接口
本系统以一个友好而简单的界面呈现给用户,如下图:
图3.4客户端界面图
图3.5客户端界面图
3.2.2软件系统接口
(1)客户端与客户端之间的通讯。
采用TCP通讯协议。
发起下载客户端发送给接收下载客户端之间的命令格式:
URL
Startbytes
Endbytes
#
(2)客户端与服务器端之间的通讯。
采用TCP通讯协议。
客户端发送给服务器端的命令格式:
Status
IP
#
其中状态包括:
ON系统启动END系统关闭NEW新建下载任务CHANGE改变用户。
服务器返回客户端的命令格式:
IP
…/…/…
#
3.2.3软件内部接口
表3.1主要的模块接口表
接口名称
传递参数
接口说明
CHttpDowndLoad:
:
DownLoad()
下载基本信息
下载服务器资源
CHttpDowndLoad:
:
TestLink()
url
测试能否连接服务器
CHttpDowndLoad:
:
MTConnectThread()
用户IP地址
连接参与下载的用户
CHttpDowndLoad:
:
MTServerThreadAccept()
无
创建监听对象
CHttpDowndLoad:
:
SendData()
连接套接字
发送数据
3.3数据库设计
表3.2UserIP用户信息表
字段名
类型
说明
备注
UserID
Int
用户ID号
主键,自动标识
UserIP
Varchar(16)
用户IP地址
-
Status
Int
用户状态
-1为封锁0为离
线,1为在线
表3.3UserDownInfo用户下载资源信息表
字段名
类型
说明
备注
InfoID
Int
资源ID
主键,自动标识
UserIP
Varchar(16)
用户IP地址
-
URL
Varchar
资源下载的url地址
-
Path
Varchar
资源存放路径
-
FileName
Varchar
资源存放名称
-
DownTime
Date
下载时间
-
FinishFlag
Int
完成标志
0为未完成,1为完成
Forbid
Int
封锁标志
-1为封锁,0为正
常
第四章详细设计
4.1基本设计概念和处理流程
创建下载任务模块表示需要下载某一资源的用户所用的模块,其工作流程图:
图4.1发起下载管理模块工作流程图
接收下载命令模块表示接收发起机的下载命令进行下载,其流程图如图4.2
图4.2接收下载管理模块工作流程图
用户IP管理服务器,用来管理在线用户,提供客户机可参与下载的用户IP信息。
其工作流程图如下:
图4.3服务器端工作流程图
4.2关键技术代码
1.下载资源代码
UINTCHttpDowndLoad:
:
DownLoad(LPVOIDpParam)
{
CHttpSocketHttpSocket1;
IDInfo*IdInfo;
IdInfo=newIDInfo;
IdInfo=(IDInfo*)pParam;
constchar*pRequestHeader=NULL;
char*pResponseHeader=NULL;
char*pAcceptType=NULL;
longnLength;
DWORDdwServiceType;
CStringstrServer;
CStringstrObject;
unsignedshortnPort;
//得到视图类的指针
//CDownLoadView*dlv;
CMDIFrameWnd*pFrame=(CMDIFrameWnd*)AfxGetApp()->m_pMainWnd;
//GettheactiveMDIchildwindow.
CMDIChildWnd*pChild=(CMDIChildWnd*)pFrame->GetActiveFrame();
//GettheactiveviewattachedtotheactiveMDIchildwindow.
POSITIONpos=pChild->GetActiveDocument()->GetFirstViewPosition();
CDownLoadView*pView=(CDownLoadView*)pChild->GetActiveDocument()->GetNextView(pos);
CFile*DownloadFile;//打开在StartHttpDownLoad()中创建的文件
DownloadFile=newCFile;
DownloadFile->Open(pView->m_taskdowninfo[IdInfo->TaskID].savepath+pView->m_taskdowninfo[IdInfo->TaskID].filename,CFile:
:
modeWrite|CFile:
:
shareDenyNone);
HttpSocket1.CloseSocket;
AfxParseURL((LPCTSTR)(pView->m_taskdowninfo[IdInfo->TaskID].url),dwServiceType,strServer,strObject,nPort);
pRequestHeader=HttpSocket1.FormatRequestHeader((LPTSTR)(LPCTSTR)strServer,(LPTSTR)(LPCTSTR)strObject,nLength,NULL,NULL,pView->m_taskdowninfo[IdInfo->TaskID].ThreadDownInfo[IdInfo->ThreadID].FromBytes,pView->m_taskdowninfo[IdInfo->TaskID].ThreadDownInfo[IdInfo->ThreadID].ToBytes,0,NULL);DownloadFile->Seek(pView->m_taskdowninfo[IdInfo->TaskID].ThreadDownInfo[IdInfo->ThreadID].FromBytes,CFile:
:
begin);//设置文件指针位置*/
HttpSocket1.Socket();
HttpSocket1.Connect((LPTSTR)(LPCTSTR)strServer,nPort);
HttpSocket1.SendRequest();
pResponseHeader=HttpSocket1.GetResponseCharPoint();
intnSvrState=HttpSocket1.GetServerState();
CStringcsState;
csState.Format("%d",nSvrState);
csState=csState.Left
(1);
if(csState=="2")
{
charpData[5024];//用于存放接收数据的字符数组
longnReceSize=0;//实际接收数据的长度(服务器返回来的值)
CStringfpath;
longrsize,sendsize;
rsize=0;
sendsize=0;
longnsize;
charbuf1[5024];nsize=pView->m_taskdowninfo[IdInfo->TaskID].ThreadDownInfo[IdInfo->ThreadID].ToBytes-pView->m_taskdowninfo[IdInfo->TaskID].ThreadDownInfo[IdInfo->ThreadID].FromBytes;
while(rsize{
nReceSize=HttpSocket1.Receive(pData,5024);
if(nReceSize<=0)
{
HttpSocket1.CloseSocket();//没有可以接收的数据,关闭Socket
AfxMessageBox("没有可接收的数据");
break;//returnwhile(TRUE)!
}
DownloadFile->Write(pData,nReceSize);
rsize=rsize+nReceSize;
pView->m_taskdowninfo[IdInfo->TaskID].finishsize+=nReceSize;
}
DownloadFile->Close();pView->m_taskdowninfo[IdInfo->TaskID].ThreadDownInfo[IdInfo->ThreadID].FinishFlag=true;
:
:
PostMessage(pView->m_hWnd,WM_SENDDATA,0,(long)&IdInfo);
}
return0;
}
2.连接其他用户代码
UINTCHttpDowndLoad:
:
MTConnectThread(LPVOIDpParam)
{
//得到视图类的指针
//CDownLoadView*dlv;
CMDIFrameWnd*pFrame=(CMDIFrameWnd*)AfxGetApp()->m_pMainWnd;
//GettheactiveMDIchildwindow.
CMDIChildWnd*pChild=(CMDIChildWnd*)pFrame->GetActiveFrame();
//GettheactiveviewattachedtotheactiveMDIchildwindow.
POSITIONpos=pChild->GetActiveDocument()->GetFirstViewPosition();
CDownLoadView*pView=(CDownLoadView*)pChild->GetActiveDocument()->GetNextView(pos);
IDInfo*IdInfo;
IdInfo=newIDInfo;
IdInfo=(IDInfo*)pParam;
charbuf[1024];
sockaddr_inaddr;
addr.sin_addr.S_un.S_addr=inet_addr(pView->m_taskdowninfo[IdInfo->TaskID].UserDownInfo[IdInfo->ThreadID].UserIP);
addr.sin_family=AF_INET;
addr.sin_port=LOCAL_PORT;
WSADATAwsaData;
WSAStartup(0x101,&wsaData);
SOCKETg_ConnectSocket;
g_ConnectSocket=socket(AF_INET,SOCK_STREAM,0);
if(g_ConnectSocket==INVALID_SOCKET)
{
return-1;
}
if(connect(g_ConnectSocket,(sockaddr*)&addr,sizeof(addr))==-1)
{
AfxMessageBox("无法连接到客户机");
return-1;
}
pView->m_taskdowninfo[IdInfo->TaskID].UserDownInfo[IdInfo->ThreadID].s=g_ConnectSocket;
CStringtemp,finishsize,fromsize;
fromsize.Format("%d",pView->m_taskdowninfo[IdInfo->TaskID].UserDownInfo[IdInfo->ThreadID].FromBytes);
finishsize.Format("%d",pView->m_taskdowninfo[IdInfo->TaskID].UserDownInfo[IdInfo->ThreadID].ToBytes);
temp="URL:
";
temp+=pView->m_taskdowninfo[IdInfo->TaskID].url;
temp+="lfromsize:
";
temp+=fromsize;
temp+="lfinishsize:
";
temp+=finishsize;
temp+="#";
strcpy(buf,temp);
intslen;
slen=0;
inttlen;
tlen=temp.GetLength();
while(slenslen+=send(g_ConnectSocket,buf,tlen,0);
CStringtemp