定位:
基于http,ftp协议的多线程下载工具,支持断点续传。
axel github代码:axel
ubuntu16.04下载:
apt-get install axel
使用方法:
1.man axel
2.axel -h
axel -o target url
改目标文件名称
axel -s xx url
指定最大下载速度
axel -n x url
指定最大连接数
axel -N url
不使用代理服务器
axel -V
查看版本
axel -q url
不把信息输出到stdout
axel -a url
显示不同的线程的进度和状态,和当前的速度并且显示剩余时间
axel -h
显示参数的大概信息
axel -v
一些状态信息
我想实现一个基于http协议的多线程断点续传工具。
目前先考虑多线程。
我的实现思路:
在此之前,需要一些http请求头的小知识:
http请求头大致介绍
以下动作都是客户端程序的。
当你输入./myaxel 参数 url之后,程序应该做的事情是:
1构造http请求包
http请求包样例:
GET /chichi/file HTTP/1.1
Host: www.server.com:8080
Connection:keep-alive (这个头信息不重要)
如上构造一个low的http请求包
2.接收http应答包。
解析Content-Length:xxx\r\n。这个告诉客户端目标文件的大小,以便于程序对指定线程分配具体下载该文件哪一部分。
解析http应答包,发现Accpet-Ranges:bytes\r\n 才可以继续第三步。
一旦要开线程去构造http请求包,那一定要让一个线程一个socket去和服务器链接,这样能进可能的占用服务器的资源,提高下载速度。因为如果一个套接字的发送缓冲区和接收缓冲区都只有一个。同理线程们接收服务器应答包时候也是,共用socket会涉及到线程共用的寄存器,和缓冲区,不仅慢,数据也有可能被覆盖或者错乱1。
3.构造http请求包,用来读物文件内容
根据文件大小和用户指定的线程数目,开辟线程,每一个线程都要连接服务器,有自己的socket。在线程所发送的http请求包中使用Range:bytes=xxx-xxx\r\n,来告诉服务器该请求在请求文件的哪一部分。
4.接收http应答包。
应答包状态此时会变为206,根据Connect-Range:xxx-xxx/文件总长度,用c++随机读取文件的操作,把接到的数据写入文件。这里我认为不用上锁,因为一旦在客户端创建了大小和目标文件一样的文件,文件大小确定,那么每一个线程所接收数据对应的读写位置就不会改变。线程虽然都往一个文件写数据,但是彼此不会影响。
还没考虑断点续传。先留个坑吧。