http下载是如今网络里最主要的下载方式,而且下载工具数不胜数,像flashget,网络蚂蚁,迅雷等等,这些工具最主要的优点是能稳定的进行多点断点续传下载,下面我们最主要以http下载协议来说明多点断点下载模型的模型。
在异步socket模型下(CAsyncSocket派生),我们建立单线程多点下载模型,考虑到市面上最流行的比如说flashGet等下载工具(多线程多点下载),其socket模型最主要的优点时 每个socket动态分配任务大小,可以动态增加和减少socket的个数,而且,当某一个socket挂了之后,其它socket可以完成其未完成的任务。。说了半天,自己的表达能力很差,还是直接用数字表示吧,呵呵。
首先,我们的socket模型必须要做到以下基本的几点:
1 。完成自己的任务。
2。完成自己的任务后会协助其它socket完成剩下的任务。
3。保证自己的稳定性,重试机制。
4。当网络不稳定导致某一个socket挂了(dead,never can be retry again),其它socket应该可以检测到而且能帮助其完成剩余的任务。
以上面几点,我考虑这个socket模型的时候走了不少弯路,以前的想法是静态分配socket的任务(缺点是明显的,若一个socket挂了,这个socket的任务就没办法完成了)
这里给出一个比较好的模型:用数组。当我们发送http header得到服务器的responsed之后,分析得到这个要下载的文件的大小,建立如下几个数组:
m_nSocketTaskArray[【MAX_SOCKET】, 记录每一个socket的起点位置
m_nSocketCompletedArray【MAX_SOCKET】,记录每一个socket的完成数
m_bSocketRunningArray【MAX_SOCKET】,记录某一个socket是否正在运行
m_bSocketFinishedArray【MAX_SOCKET】,记录某一个socket是否已经完成.
我的思路是:初始时,初始化所有的数组,像flashGet一样,一开始,我们只以一个socket去得到文件大小nTotalSize,(我们只考虑没有错误的情况下),当这个socket得到文件大小之后,其它socket开始工作。每个socket的任务是这样分配的:由nTotalSize/nTotalBlock * i 得到每一个socket的开始位置,而结束位置都为nTotalSize,这样的话,我们就防止了服务器限制线程的结果,但是又出现了一个问题:怎么样决定每个socket的实际任务。这时候,上面的数组就派上用场了,我们对数组操作有一个原则:当某个socket得到正确的http responsed 之后才插入m_nSocketTaskArray数组,m_nSocketTaskArray数组是由小到大排列的。
而其它数组是以m_nSocketTaskArray为定位的,如m_nSocketCompletedArray【i】记录的就是以m_nSocketTaskArray【i】为开始的socket的完成数。这时,我们每当插入一个socket的任务的时候,更新每一个socket的任务.如socket[i]的任务是以m_nSocketTaskArray[i]为开始,m_nSocketTaskArray[i+1]-1为结尾。如分10块文件下载长度为1000时:
m_nSocketTaskArray 0 100 200 300 400 1000 0 0
m_nSocketCompletedArray 51 41 21 100 200 0 0 0
m_bSocketRunning 1 0 1 0 1 0 0 0
m_bSocketCompleted 0 0 0 1 0 0 0 0
m_nSocketTaskArray里面只记录得到responsed后的socket的开始处, socket6,7,8,9可能因为服务器的限制而启动不成功,所以,不在数组里面,我们这种排列保证了每一块都有socket去完成,排除了服务器限制线程的情况,至于Socket从400到1000任务太重了,这时候我们就要考虑socket的智能机制了,如socket从0到100完成任务后,应该去帮助最繁重的任务,这个我们下次再说了。
表达能力不是很好,多多见量