分享
 
 
 

Linux平台的下载程序

王朝system·作者佚名  2006-11-24
窄屏简体版  字體: |||超大  

有许多网络文件下载工具可以在Windows平台下很好地工作,如NetAnts、“网际快车”、TelePro等,还有像WebZip那样功能强大的离线浏览器。这些工具使我们可以在Windows环境下很轻松地下载网站上的文件、目录、网站的一部分,甚至整个网站。然而在Linux环境下,这类工具却很少。笔者通过自己的摸索,在集成开发环境KDevelop1.2下实现了一个网站下载程序,它支持文件级的“多线程下载”和“断点续传”。下面本文分3部分介绍实现这一程序的基本技术。

基本原理

1.超级链接寻径算法

要想灵活地下载一个网站的全部或部分内容,程序就必需具备从用户指定的URL开始,沿着它所包含的超级链接遍历整个网站的能力。在这个基础上根据用户的限制,筛选出所要下载的文件。

从“图论”的角度分析,网站其实是一个由文件和超级链接组成的“连通有向图”。文件是图中的顶点,超级链接是有向边。我们需要对这个有向图进行“广度优先遍历”。为此,需要用一个队列URLQueue来存放待访问的目标。初始情况下,队列中只含有用户指定的那个URL。程序从队头取得下载目标的URL,如果它符合用户的限制,就下载它指向的文件。分析此文件,找出其中包括的超级链接,生成新的下载目标的URL,然后将它们插入到队列尾部。重复以上过程,直到队列中没有符合用户限制的URL为止。

由于网站是一个“连通有向图”,所以沿着超级链接,很可能回到已经访问过的文件。为了避免程序出现死循环,要登记已经访问过的目标。在分析下载文件的超级链接时,我们要将生成的新目标的URL与已经访问过的进行比较,剔除会造成重复访问的URL。为了提高查询速度,我们采用了“哈希表”来存放从队头取出的URL。“哈希函数”可以采用将URL中的字符作为整型值相加,然后模一个质数的简单方法来实现。在本文介绍的程序中使用了质数103。

2.多线程下载和断点续传

多线程下载和断点续传使用了同一个技术。HTTP协议允许客户端在向服务器端发送下载一个文件的GET请求时,使用“Range:bytes=a1-a2"选项,要求服务器只传送指定文件中从第a1个字节到a2个字节之间的部分内容。因此下载一个文件时,可以将其分成若干段,然后启动多个线程,同时与服务器建立链接,分别传送一个文件的多个部分。最后在本地将其拼接成一个完整的文件。由于从网上下载文件时,瓶颈是在服务器端和网络传输过程中,所以采用多线程同时下载将大大提高下载速度。

当文件传输因出现问题而中断时,程序可以将各个线程当前下载的进度和已经下载的内容当做“断点信息”保存到文件中。用户下一次下载同一目标时,程序可以根据文件中保留的断点信息下载上次未完成的部分,然后将整个文件拼接起来,完成下载工作。这种技术对于在经常“掉线”的情况下下载大文件非常有利。因此,在当前流行的下载软件中都采用了此项技术。

Linux如何启动线程

1.定义一个以void*为参数、返回void*的函数。例如,为了启动下载线程,需要定义如下函数:

void*start(void*arg)

{

((CWebCopy*)arg)->DownLoad();

returnarg;

}

2.在需要启动线程时,只要三条语句。例如,启动下载线程的代码如下:

#include

pthread_ttid;

pthread_create(&tid,NULL,start,arg);

部分程序的实现

由于篇幅有限,在这里我们只给出主控程序(图1)和下载控制线程(图2)的流程图,并给出下载线程的算法描述。

图1主控程序的流程图

图2下载控制线程的流程图

以下是下载线程中三个关键性函数的算法描述(假定这三个函数都被封装在CwebCopy类中)。

intCWebCopy::DownLoad(char*host,char*path,inta1,inta2,BYTE*buf)

{

//本函数从host所指定的HTTP服务器上下载路径为path的文件中从第a1字节到第a2字节的内容,与host所指定的主机的80端口(HTTP端口)建立流式链接,共尝试5次

boolconnected=false;

intsock;//用于存放套接字描述符

for(i=0;i<5;i++){

if((sock=Connect(host,80))<0)

sleep(1);

else{

connected=true;

break;

}

}

if(connected){

//向指定的HTTP服务器发送GET请求,下载当前指定路径下的文件的一部分

Send(sock,“GETpath%cHost:%s%cRange:bytes=%d-%d%c”,path,10,host,10,a1,a2,10);

intinflen,index=0;

while(1){

structtimevaltv;

tv.tv_sec=1;

tv.tv_usec=0;

//检查套接字是否接收到了数据,尝试20次,每次间隔1秒

intreaden;

readen=ReadEn(sock,tv,20);

//如果套接字中20秒内仍然没有数据,则认为超时

if(readen<1)return-1;

//接收数据,并存放在信息缓冲区中

inflen=read(sock,(buf+index),a2-a1);//如果此文件所需部分已经下载结束

if(inflen<=0)break;

}

return0;

}

elsereturn-1;

}

intCWebCopy::Send(intsock,char*fmt,...)

{

//本函数将指定的字符串发送到sock所指向的远程HTTP服务器

charBUF[1024];

va_listargptr;

//处理可变个数参数

va_start(argptr,fmt);

//将参数整理成字符串后放入BUF中

vsprintf(BUF,fmt,argptr);

va_end(argptr);

//将BUF中的字符串发送到sock所指向的远程服务器

returnsend(sock,BUF,strlen(BUF),0);

}

intCWebCopy::ReadEn(intsock,structtimevaltv,inttryloop)

{

//利用select函数检验套接字sock,如果套接字接收到数据则返回“读使能”,如果出现“内部中断”以外的错误,则返回“读禁止”

fd_setrfdset;

FD_ZERO(&rfdset);

FD_SET(sock,&rfdset);

intreaden=0;

for(inti=0;i<tryloop;i++){

readen=select(m_sock+1,&rfdset,NULL,NULL,&tv);

if(readen>0||(readen<0&&errno!=EINTR))

break;

sleep(1);

}

returnreaden;

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有