闲来无事,研究了下HTTP的断点续传,用VB6写了小Demo。

关于HTTP-Range细节可参考:

  http://www.w3.org/Protocols/rfc2616/rfc2616.html

  http://www.liqwei.com/network/protocol/2011/886.shtml

以在“下载吧”下载notepad++的安装程序为例,其主要流程为:

  1.判断资源是否支持断点续传。

  2.如果支持则返回文件的大小,用作后面做分段任务使用。

  3.将下载任务分成4个任务流(姑且把winsock当做多线程来看),然后按照文件大小分配下载额度。

  4.启动下载的任务流后,监视下载完成度。

  5.文件下载完成后,合并到本地。

测试了下,5.4M的程序下载大约在5秒钟左右就完成了(应该不是我网速快的原因),还是很快的。像那个下载工具IDM(Internet Download Manger)原理上就跟这个Demo差不多。由于用了控件不太好封装了,看到那些公共变量也是醉了,菜手捂脸遁了。另外,我这个Demo因为下载的文件较小,将数据完全存在内存中。如果是大文件,还是要先落地再合并。

具体实现代码:

Private Declare Function GetTickCount Lib "kernel32" () As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, _
Source As Any, _
ByVal Length As Long) '分段下载的任务属性
Private Type RangeTask
host As String
port As Integer
head As String
buff() As Byte
size As Long
done As Boolean
End Type '定义任务组
Private Tasks() As RangeTask '延时函数
Private Sub Sleep(ByVal dwDelay As Long)
Dim dwDeadline As Long
dwDeadline = GetTickCount() + dedelay
Do While dwdeadlin > GetTickCount()
DoEvents
Loop
End Sub '判断资源是否支持断点续传
Private Function IsServerRanged(ByVal url As String, ByRef Length As Long) As Boolean
On Error GoTo ERROR_HANDLER:
IsServerRanged = False
Dim http As Object
Const USER_AGENT = "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.0 Safari/537.36" Set http = CreateObject("msxml2.xmlhttp")
Call http.Open("HEAD", url, False)
Call http.setRequestHeader("User-Agent", USER_AGENT)
Call http.send Do Until http.readyState =
Call Sleep()
Loop If http.getResponseHeader("Accept-Ranges") <> "" Then
IsServerRanged = True
Length = http.getResponseHeader("Content-Length")
End If ERROR_HANDLER:
Err.Clear
Set http = Nothing
End Function '分配任务,主要计算Range的起止点
Private Sub TaskAssignment(ByVal url As String, ByVal Length As Long)
ReDim Tasks() As RangeTask
temp = Split(url, "/")()
If InStr(temp, ":") Then
host = Split(temp, ":")()
port = Split(temp, ":")()
Else
host = temp
port =
End If
file = "/" & Split(url, "/", )()
over = Length Mod
ttmp = (Length - (Length Mod )) / For i = To
Tasks(i).host = host
Tasks(i).port = port
Tasks(i).size = ttmp + IIf(i = , over, )
ReDim Tasks(i).buff(Tasks(i).size - ) As Byte
Tasks(i).head = "GET " & file & " HTTP/1.1" & vbCrLf & _
"Host: " & host & vbCrLf & _
"Connection: closed" & vbCrLf & _
"User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.0 Safari/537.36" & vbCrLf & _
"Accept: */*" & vbCrLf & _
"Accept-Encoding: gzip,deflate,sdch" & vbCrLf & _
"Range: bytes=" & i * ttmp & "-" & (i + ) * ttmp + IIf(i = , over, ) - & vbCrLf & vbCrLf
Tasks(i).done = False
Next
End Sub '启动分段下载
Private Sub SetupRangeTasks()
For i = To
RangeLoader(i).Protocol = sckTCPProtocol
RangeLoader(i).RemoteHost = Tasks(i).host
RangeLoader(i).RemotePort = Tasks(i).port
RangeLoader(i).Connect
Next
End Sub '将下载完的字节写入本地文件
Private Sub BuildRangeFile(ByVal filepath As String)
Open filepath For Binary Access Write As #
For i = To
Put #, , Tasks(i).buff
Erase Tasks(i).buff
Next
Close #
Erase Tasks
End Sub '各段下载完毕
Private Sub RangeLoader_Close(Index As Integer)
Call RangeLoader(Index).Close
Tasks(Index).done = True
For i = To
If Not Tasks(i).done Then
Exit Sub
End If
Next
Call BuildRangeFile("d:\NotepadPlusPlus_6.6.9_XiaZaiBa.exe")
Debug.Print "END", Now()
End Sub '与Server端连接后,GET文件
Private Sub RangeLoader_Connect(Index As Integer)
Call RangeLoader(Index).SendData(Tasks(Index).head)
End Sub '数据接收时,计算下载率
'如果下载完成则拷贝出原始数据
Private Sub RangeLoader_DataArrival(Index As Integer, ByVal bytesTotal As Long)
If RangeLoader(Index).BytesReceived > Tasks(Index).size Then
Dim buff() As Byte
Call RangeLoader(Index).GetData(buff, vbByte)
Call CopyMemory(Tasks(Index).buff(), buff(UBound(buff) - Tasks(Index).size + ), Tasks(Index).size)
Erase buff
Else
     '这个WinSock貌似每次下载的数据量都在3752字节左右
Debug.Print "RangeLoader"; Index, Round(RangeLoader(Index).BytesReceived / Tasks(i).size * , ) & "%"
End If
End Sub '下载文件
Private Sub Command1_Click()
Dim url As String
Dim Length As Long
url = "http://xiazai.xiazaiba.com/Soft/N/NotepadPlusPlus_6.6.9_XiaZaiBa.exe"
If IsServerRanged(url, Length) Then
Call TaskAssignment(url, Length)
Call SetupRangeTasks
Debug.Print "START", Now()
Else
Debug.Print "task cannot be ranged."
End If
End Sub

运行后信息输出大体是这个样子:

立即窗口:

START        // ::
...
RangeLoader 89.53%
RangeLoader 89.8%
RangeLoader 89.8%
RangeLoader 86.76%
RangeLoader 82.2%
RangeLoader 82.22%
RangeLoader 90.07%
RangeLoader 82.47%
RangeLoader 90.33%
RangeLoader 86.88%
RangeLoader 87.02%
RangeLoader 82.73%
RangeLoader 82.8%
RangeLoader 90.38%
RangeLoader %
RangeLoader 90.87%
RangeLoader 87.46%
RangeLoader 83.27%
RangeLoader 83.38%
RangeLoader 90.96%
RangeLoader 87.46%
RangeLoader 83.53%
RangeLoader 91.4%
RangeLoader 87.72%
RangeLoader 83.97%
RangeLoader 91.55%
RangeLoader 84.07%
RangeLoader 88.05%
RangeLoader 91.94%
RangeLoader 88.26%
RangeLoader 84.34%
RangeLoader 92.13%
RangeLoader 88.63%
RangeLoader 92.71%
RangeLoader 88.79%
...
END // ::

VB6之断点续传的更多相关文章

  1. HTML5实现文件断点续传

    HTML5的FILE api,有一个slice方法,可以将BLOB对象进行分割.前端通过FileList对象获取到相应的文件,按照指定的分割方式将大文件分段,然后一段一段地传给后端,后端再按顺序一段段 ...

  2. 总结iOS开发中的断点续传那些事儿

    前言 断点续传概述 断点续传就是从文件赏赐中断的地方重新开始下载或者上传数据,而不是从头文件开始.当下载大文件的时候,如果没有实现断点续传功能,那么每次出现异常或者用户主动的暂停,都会从头下载,这样很 ...

  3. (实例篇)PHP实现HTTP断点续传的方法

    PHP实现HTTP断点续传的方法. <?php /** * PHP-HTTP断点续传实现 * @param string $path: 文件所在路径 * @param string $file: ...

  4. C# 文件下载之断点续传

    注意,本文所说的断点续传特指 HTTP 协议中的断点续传.本文主要聊聊思路和关键代码,更多细节请参考本文附带的 demo. 工作原理 HTTP 协议中定义了一些请求/响应头,通过组合使用这些头信息.我 ...

  5. chunkupload文件上传断点续传组件(java)

    chunkupload简介 chunkupload是一款基于java语言的断点续传组件,针对文件上传,非文件下载,集成方便,使用简单. 从整体上讲,chunkupload会对文件进行切片处理,每个切片 ...

  6. VB6史无前例的子类化之透明按钮

    [原创文章,转发请保留版权信息] 作者:mezstd 文章地址:http://www.cnblogs.com/imez/p/3299728.html 效果图: 请原谅笔者无耻地称之为史无前例,至少在笔 ...

  7. wget 断点续传 & nginx文件服务器

    nginx默认支持断点续传: 测试方法: wget -S http://httpd.apache.org/images/httpd_logo_wide_new.png 2>&1 | gr ...

  8. VB6与VB.NET对照表

    VB6与VB.NET对照表 VB6.0 VB.NET AddItem Object名.AddItem Object名.Items.Add ListBox1.Items.Add ComboBox1.It ...

  9. 自写函数VB6 STUFF函数 和 VB.net 2010 STUFF函数 详解

    '*************************************************************************'**模 块 名:自写函数VB6 STUFF函数 和 ...

随机推荐

  1. 【Netty】Netty之ByteBuf

    一.前言 前面已经学习了Netty中传输部分,现在接着学习Netty中的ByteBuf. 二.ByteBuf 2.1 ByteBuf API 在网络上传输的数据形式为Byte,Java NIO提供了B ...

  2. VueJs生产环境部署

    VueJs为客户端语言,所以部署的时候是不需要基于nodejs或其他服务器运行环境,只需要像其他静态站点的方式发布就可以了,下面介绍一下VueJs具体发布的流程还有需要注意的点. 先来看VueJs最终 ...

  3. SparkR安装部署及数据分析实例

    1. SparkR的安装配置 1.1.       R与Rstudio的安装 1.1.1.           R的安装 我们的工作环境都是在Ubuntu下操作的,所以只介绍Ubuntu下安装R的方法 ...

  4. TextView 实现跑马灯效果

    在String.xml中添加: <string name="txt">跑马灯效果,我跑啊跑</string>在layout/mian.xml中添加TextV ...

  5. C语言之变量和数据类型

    常量:程序在运行过程中无法对值进行更改. 变量:是在计算机内存空间一种表示,声明变量将会向计算机内存申请存储空间,用于保存数据,计算机的CPU会从内存中加载数据. 声明变量: 数据类型  变量名[=值 ...

  6. python基础 --02

    常见的数据类型 列表 在python中,列表的创建可以是由[]两个方括号组成的.在其他语言中,被称之为数组. 列表里可以存放一组值,并且系统默认的给列表里的每一个元素以索引值,方便查找和使用. 如下: ...

  7. 网络编程2之Socket简介和java.net包

    一.Socket 通信链路的端点就被称为"套接字"(英文名Socket) 是提供给应用程序的接口 图文说明Socket Socket通信原理 二.java.net包 Java.ne ...

  8. javaSE_08Java中static、继承、重写

    一.Static 学习静态这个关键字,关键是抓住两个点: 1,关注其语法特点 2,关注其使用场景 案例讲解: 我们先从静态变量开始,当一个成员变量加上static修饰之后,会是一个什么效果? 比如创建 ...

  9. weex入门

    近期要做一个安卓端的原生应用程序.情况是这样的:需求方原先已经实现了网页,是一个工具类应用,大致作用是连接到他们公司生产的硬件,然后通手机与智能硬件通信来对硬件进行一系列控制.不过呢,这个网页先前是由 ...

  10. hive报错 Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. MetaException(message:For direct MetaStore DB connections,

    学习hive 使用mysql作为元数据  hive创建数据库和切换数据库都是可以的 但是创建表就是出问题 百度之后发现 是编码问题 特别记录一下~~~ 1.报错前如图: 2.在mysql数据库中执行如 ...