博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
VB6之断点续传
阅读量:5226 次
发布时间:2019-06-14

本文共 6099 字,大约阅读时间需要 20 分钟。

闲来无事,研究了下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 LongPrivate 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 BooleanEnd Type'定义任务组Private Tasks() As RangeTask'延时函数Private Sub Sleep(ByVal dwDelay As Long)    Dim dwDeadline As Long    dwDeadline = GetTickCount() + dedelay    Do While dwdeadlin > GetTickCount()        DoEvents    LoopEnd Sub'判断资源是否支持断点续传Private Function IsServerRanged(ByVal url As String, ByRef Length As Long) As BooleanOn 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 = 4        Call Sleep(50)    Loop        If http.getResponseHeader("Accept-Ranges") <> "" Then        IsServerRanged = True        Length = http.getResponseHeader("Content-Length")    End If    ERROR_HANDLER:    Err.Clear    Set http = NothingEnd Function'分配任务,主要计算Range的起止点Private Sub TaskAssignment(ByVal url As String, ByVal Length As Long)    ReDim Tasks(3) As RangeTask    temp = Split(url, "/")(2)    If InStr(temp, ":") Then        host = Split(temp, ":")(0)        port = Split(temp, ":")(1)    Else        host = temp        port = 80    End If    file = "/" & Split(url, "/", 4)(3)    over = Length Mod 4    ttmp = (Length - (Length Mod 4)) / 4        For i = 0 To 3        Tasks(i).host = host        Tasks(i).port = port        Tasks(i).size = ttmp + IIf(i = 3, over, 0)        ReDim Tasks(i).buff(Tasks(i).size - 1) 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 + 1) * ttmp + IIf(i = 3, over, 0) - 1 & vbCrLf & vbCrLf        Tasks(i).done = False    NextEnd Sub'启动分段下载Private Sub SetupRangeTasks()    For i = 0 To 3        RangeLoader(i).Protocol = sckTCPProtocol        RangeLoader(i).RemoteHost = Tasks(i).host        RangeLoader(i).RemotePort = Tasks(i).port        RangeLoader(i).Connect    NextEnd Sub'将下载完的字节写入本地文件Private Sub BuildRangeFile(ByVal filepath As String)    Open filepath For Binary Access Write As #1    For i = 0 To 3        Put #1, , Tasks(i).buff        Erase Tasks(i).buff    Next    Close #1    Erase TasksEnd Sub'各段下载完毕Private Sub RangeLoader_Close(Index As Integer)    Call RangeLoader(Index).Close    Tasks(Index).done = True    For i = 0 To 3        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(0), buff(UBound(buff) - Tasks(Index).size + 1), Tasks(Index).size)        Erase buff    Else      '这个WinSock貌似每次下载的数据量都在3752字节左右        Debug.Print "RangeLoader"; Index, Round(RangeLoader(Index).BytesReceived / Tasks(i).size * 100, 2) & "%"    End IfEnd 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 IfEnd Sub

 

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

立即窗口:START        2014/12/1 16:12:34...RangeLoader 3               89.53%RangeLoader 3               89.8%RangeLoader 3               89.8%RangeLoader 0               86.76%RangeLoader 2               82.2%RangeLoader 2               82.22%RangeLoader 3               90.07%RangeLoader 2               82.47%RangeLoader 3               90.33%RangeLoader 0               86.88%RangeLoader 0               87.02%RangeLoader 2               82.73%RangeLoader 2               82.8%RangeLoader 3               90.38%RangeLoader 2               83%RangeLoader 3               90.87%RangeLoader 0               87.46%RangeLoader 2               83.27%RangeLoader 2               83.38%RangeLoader 3               90.96%RangeLoader 0               87.46%RangeLoader 2               83.53%RangeLoader 3               91.4%RangeLoader 0               87.72%RangeLoader 2               83.97%RangeLoader 3               91.55%RangeLoader 2               84.07%RangeLoader 0               88.05%RangeLoader 3               91.94%RangeLoader 0               88.26%RangeLoader 2               84.34%RangeLoader 3               92.13%RangeLoader 0               88.63%RangeLoader 3               92.71%RangeLoader 0               88.79%...END           2014/12/1 16:12:39

 

转载于:https://www.cnblogs.com/lichmama/p/4135429.html

你可能感兴趣的文章
POJ 3301 Texas Trip (三分)
查看>>
java(配置eclipse )
查看>>
python - 简明 性能测试
查看>>
C扩展python的module和Type
查看>>
asp.net 文件压缩zip下载
查看>>
html
查看>>
Linux命令(二十二) 改变文件权限 chomd
查看>>
数据不均衡问题
查看>>
开源:ASP.NET MVC+EF6+Bootstrap开发框架
查看>>
C# 并行任务——Parallel类
查看>>
关于iOS7.0以后修改navigationBar的返回按钮的文本、颜色、自定义按钮等等
查看>>
c#中string的一些基本用法
查看>>
Three.js创建简单和复杂三维几何图、创建动画、移动物体、添加纹理材质并使用dat.GUI简化实验流程...
查看>>
49:把字符串转换为整数
查看>>
HDU-6031 Innumerable Ancestors(二分+树上倍增)
查看>>
流媒体协议(二):RTMP协议
查看>>
linux下的find文件查找命令与grep文件内容查找命令
查看>>
swift 数组
查看>>
SQL存储过程学习笔记
查看>>
爱情16谈
查看>>