利用Winsock下载文件(支持断点续传)

原创 2004年09月29日 14:10:00
第一步,建立工程,引用Winsock(Visual Basic最好打SP6,否则MS有一个Bug),在此省略

第二步,具体实现代码步骤1:发送请求
说明:
(1)这里简单采用了判断是否已经有同名文件表示是否要断点续传
(2)下载的地址,大小和已下载字节数也只是简单地存在ini文件中,更安全的做法本文不作讨论
有兴趣的朋友可以联系我

'--------------------------------------------------------------------------------
'   Name:DownloadFile
'   Author:Reker 2004/3/20
'   Desc:连接远端主机,发送接收文件请求,等待远端主机响应
'   Params:None
'   History:None
'--------------------------------------------------------------------------------
Private Sub DownloadFile()
    On Error Resume Next
    StartTime = Time()
    With WinSck
        .RemoteHost = Host '远端主机地址
        .RemotePort = 80
        .Connect
        '等待服务器连接相应
        Do While .State <> sckConnected
            DoEvents: DoEvents: DoEvents: DoEvents
            '20秒超时
            If DateDiff("s", StartTime, Time()) > 20 Then
                ShowInfo "连接超时"
                .Close
                Exit Sub
            End If
        Loop
        '发送下载文件请求
        '此处使用HTTP/1.0协议
        strCommand = "GET " + UpdateURL + " HTTP/1.0" + vbCrLf '下载地址
        strCommand = strCommand + "Accept: */*" + vbCrLf      '这句可以不要
        strCommand = strCommand + "Accept: text/html" + vbCrLf '这句可以不要
        strCommand = strCommand + vbCrLf
        strCommand = strCommand & "Host: " & Host & vbCrLf
        If Dir(SaveFileName) <> "" Then '是否已经存在下载文件
            Dim confirm
            confirm = MsgBox("已经存在文件,是否断点续传?", vbYesNo + vbQuestion, "提示")
            If confirm = vbYes Then
                DownPosition = ""
                If Not oFileCtrl.ReadKeyFromIni("Update", "DownSize", AppPath + "Update.ini", DownPosition) Then
                '读取上次下载的字节数
                    MsgBox "读取大小错误", vbInformation, "提示"
                End If
                '发送断点续传请求
                strCommand = strCommand & "Range: bytes=" & CLng(DownPosition) & "-" & vbCrLf
            Else
                Kill SaveFileName '删除原文件
            End If
        End If
        strCommand = strCommand & "Connection: Keep-Alive" & vbCrLf
        strCommand = strCommand & vbCrLf
        .SendData strCommand
    End With
    If Err Then
        lblProcessResult.Caption = lblProcessResult.Caption & vbCrLf & vbCrLf & "下载文件出错:" & Err.Description
        lblProcessResult.Refresh
    End If
End Sub


第二步,具体实现代码步骤2:接收数据
'--------------------------------------------------------------------------------
'   Name:Winsck_DataArrival
'   Author:Reker 2004/3/20
'   Desc:略
'   Params:略
'   Return:None
'   History:None
'--------------------------------------------------------------------------------
Private Sub Winsck_DataArrival(ByVal bytesTotal As Long)
    On Error Resume Next
    'DoEvents: DoEvents
    Dim ByteData() As Byte
    WinSck.GetData ByteData(), vbByte
    ReceiveData = ReceiveData & StrConv(ByteData(), vbUnicode)
    If InStr(1, ReceiveData, "Content-Length:") > 0 And FileSize = 0 Then '仅第一次计算,FileSize=0
        Dim pos1 As Long, pos2 As Long
        pos1 = InStr(1, ReceiveData, "Content-Length:")
        pos2 = InStr(pos1 + 16, ReceiveData, vbCrLf)
        If pos2 > pos1 Then
            FileSizeByte = Mid(ReceiveData, pos1 + 16, pos2 - pos1 - 16) '计算文件的长度
            StartTime = Timer() '保存开始下载的时间
            ProgssBar.Max = FileSizeByte '设置进度条
            FileSize = FormatNumber(FileSizeByte / 1024, 2) '以KB表示
            ShowInfo "本次下载的文件共" + CStr(FileSize) + "KB..."
        End If
    End If
    '从服务器响应返回的数据查找下载文件的起始位置
    If FileHeaderLen = 0 Then
        For i = 0 To UBound(ByteData()) - 3
            If ByteData(i) = 13 And ByteData(i + 1) = 10 And ByteData(i + 2) = 13 And ByteData(i + 3) = 10 Then
                StartPos = i + 4 '将文件头的长度保存下来
                FileHeaderLen = StartPos
                Exit For
            End If
            'DoEvents 
        Next i
    End If
    FileSizeHaveDown = bytesTotal + FileSizeHaveDown - FileHeaderLen     
    '已下载文件长度,需减去响应的文件头长度
    dblDownloadSpeed = FormatNumber(FormatNumber(FileSizeHaveDown / 1024, 2) / (FormatNumber((Timer() - StartTime), 4)), 2)  '计算下载速率 KB/S
    If dblDownloadSpeed <> 0 Then  '计算剩余下载的时间
        sRestTime = GetRestTime(CLng((FileSize - (FileSizeHaveDown) / 1024) / dblDownloadSpeed)) '此过程略,可以删除此段代码
        labRestTime.Caption = "剩余时间:º" + sRestTime
        labRestTime.Refresh
    End If
    labDownloadSpeed.Caption = CStr(dblDownloadSpeed) + " kb/s"
    labDownloadSpeed.Refresh
    ProgssBar.Value = FileSizeHaveDown
    '写数据
    Fnum = FreeFile()
    Open SaveFileName For Binary Lock Write As #Fnum
    If LOF(Fnum) > 0 Then
        Seek #Fnum, LOF(Fnum) + 1
    End If
    If StartPos > 0 Then
        For i = StartPos To UBound(ByteData())
            Put #Fnum, , ByteData(i)
        Next i
    Else 
        Put #Fnum, , ByteData()
    End If
    Close #Fnum 
    If Err Then
        lblProcessResult.Caption = lblProcessResult.Caption & vbCrLf & 获取数据出错:" & Err.Description
        lblProcessResult.Refresh
    End If
End Sub

利用Xutils框架进行断点续传下载

前面有两篇博文主要介绍了如何利用volley获取所有cookie信息和自定义一个request, 地址如下: Volley 添加Cookie和获取服务器返回的一条或多条Cookie 继承Volley...
  • qiang_xi
  • qiang_xi
  • 2016年02月16日 17:06
  • 7334

HDFS下断点续传的实现——下载

本文实现了在HDFS系统下的服务端提供给客户端满足断点续传下载功能的实现代码,使用了约定偏移量策略和Hadoop api中的seek方法。...
  • u010355811
  • u010355811
  • 2017年06月02日 15:59
  • 694

使用XUtils进行文件的断点下载

使用XUtils进行文件的断点下载这个也很简单,我前面写了两篇文件下载和断点下载的相关文章,主要是就是学习了一下原理,大多数情况下,我们在工作中都是用现成的框架实现这个功能。今天就说一下xutils这...
  • wozuihaole
  • wozuihaole
  • 2017年02月08日 16:33
  • 256

C# Http文件下载公共类(支持断点续传)

请看代码 using System; using System.Collections.Generic; using System.Linq; using System.Text; using S...
  • paolei
  • paolei
  • 2014年02月17日 22:44
  • 1122

文件下载之断点续传(客户端与服务端的实现)

前面讲了文件的上传,今天来聊聊文件的下载。 老规矩,还是从最简单粗暴的开始。那么多简单算简单?多粗暴算粗暴?我告诉你可以不写一句代码,你信吗?直接把一个文件往IIS服务器上一扔,就支持下载。还TM么...
  • binyao02123202
  • binyao02123202
  • 2017年08月02日 23:29
  • 1403

基于HTTP协议用WinSock实现任意文件下载

HTTP协议是文本格式通讯,下载文件是二进制数据,怎样处理好两种格式,而不受VB独断专行的Unicode转换影响,本代码提供了一个示例。Option ExplicitPrivate strURL As...
  • homezj
  • homezj
  • 2005年04月12日 19:30
  • 3010

关于apache服务器支持断点续传的一点理解

默认情况下,当下载文件的时候会开启gzip和chunk。 但是chunk没有Content-Length,而范围响应 206 Partial Content又需要Content-Length, 这样的...
  • liumengcheng
  • liumengcheng
  • 2013年11月11日 09:50
  • 3793

新技能 get —— Python 断点续传下载文件

from urllib.request import urlretrieve
  • lanchunhui
  • lanchunhui
  • 2017年03月24日 12:44
  • 528

Net/C#: 实现支持断点续传多线程下载2

.Net/C#: 实现支持断点续传多线程下载的 Http Web 客户端工具类 (C# DIY HttpWebClient) ...
  • hellyhe
  • hellyhe
  • 2006年09月09日 15:25
  • 2531

C#: 实现支持断点续传多线程下载的

  /* .Net/C#: 实现支持断点续传多线程下载的 Http Web 客户端工具类 (C# DIY HttpWebClien...
  • vrix
  • vrix
  • 2006年07月28日 18:37
  • 1112
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:利用Winsock下载文件(支持断点续传)
举报原因:
原因补充:

(最多只允许输入30个字)