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

下载

第一步,建立工程,引用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

时间: 2024-12-02 18:56:11

利用Winsock下载文件(支持断点续传)的相关文章

在.NET中利用XMLHTTP下载文件

xml|下载      利用XMLHTTP下载文件,和以前的方法一样,先添加引用-COM-Microsoft Xml 3.0,然后在代码开始处写:      using MSXML2;   下面就是主要的代码:      private void Page_Load(object sender, System.EventArgs e)   {    string Url = "20061130113617553.gif";    string StringFileName = Url.

利用XMLHTTP下载文件

  利用XMLHTTP下载文件,和以前的方法一样,先添加引用-COM-Microsoft Xml 3.0,然后在代码开始处写: using MSXML2; 下面就是主要的代码: private void Page_Load(object sender, System.EventArgs e){  string Url = "" ; string StringFileName = Url.Substring(Url.LastIndexOf("/") + 1); str

C# 上传下载ftp(支持断点续传)

本文整理自网络,由于太多文章类似,此处标识其中一处:点击打开链接 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net.Sockets; using System.IO; using System.Net; namespace JianKunKing.Common.Ftp { /// <summary> /// FTP Client(不允许匿名

C# FTP上传下载(支持断点续传)

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net; using System.IO; namespace JianKunKing.Common.Ftp { /// <summary> /// ftp方式文件下载上传 /// </summary> public static class FileUpDownload { #regi

利用curl下载文件(进度条显示) 代码片段

在项目中需要用到程序更新的功能,同事介绍说是curl中的开发库很牛x,又是跨平台(他们 总是这么喜欢跨平台的东西 *_*),于是下载这个包测试了一下,确实不错.准备正式用到项 目中,以下一个例子用于从互联网上抓取一个文件下载到本地,并加上进度条显示,做得挺 简陋,不过功能差不多就这样了. 程序运行预览. 首先需要 加入多线程的机制,因为程序一边在下载文件,一边在显示进度条,单线程的方式肯定不行 ,所以我用到了wxTimer来实现,在downloadMain.h 中定义了一个wxTimer,并做了

Ubuntu系统利用Rsync下载文件

rsync是类unix系统下的数据镜像备份工具,从软件的命名上就可以看出来了--remote sync.它的特性如下: 可以镜像保存整个目录树和文件系统. 可以很容易做到保持原来文件的权限.时间.软硬链接等等. 无须特殊权限即可安装. 优化的流程,文件传输效率高. 可以使用rcp.ssh等方式来传输文件,当然也可以通过直接的socket连接. 支持匿名传输,以方便进行网站镜象. Ubuntu安装: sudo apt-get install rsync 需要注意的是必须在服务器A和B上都安装rsy

怎么利用WGET下载文件并保存到指定目录

  wget是Linux上一个非常不错的下载指令,而其指令的内容虽然说是非常简单,但内藏许多的参数,也算是Linux工作者常用的指令之一. 而这个指令我想在各大系统都预设有提供,包括了Ubuntu.Fedora等,而一般来说,要使用wget下载档案,只需要打以下的指令: wget 网址 而要让档案自动储存到指令的目录下,则需要借用-P这个参数,可以使用以下的指令 wget -P 目录 网址 举例来说,如果你要放到/root底下,你可以打下列的指令: wget -P /root 网址 其实还蛮方便

php支持断点续传、分块下载的类_php技巧

本文是为大家分享php支持断点续传.分块下载的类,供大家参考,具体内容如下 <?php /** * User: djunny * Date: 2016-04-29 * Time: 17:18 * Mail: 199962760@qq.com * 支持断点下载的类 */ class downloader { /** * download file to local path * * @param $url * @param $save_file * @param int $speed * @par

php的一个支持断点续传的文件下载类

php 支持断点续传,主要依靠HTTP协议中 header HTTP_RANGE实现. HTTP断点续传原理 Http头 Range.Content-Range() HTTP头中一般断点下载时才用到Range和Content-Range实体头, Range用户请求头中,指定第一个字节的位置和最后一个字节的位置,如(Range:200-300) Content-Range用于响应头 请求下载整个文件: GET /test.rar HTTP/1.1 Connection: close Host: 1