Web客户端连续下载会产生不切实际的下载速度



我正在尝试从路由器硬盘驱动器(具有某些IP地址(一个接一个地进行连续下载,直到禁用切换开关。第一次下载正常发生,它会产生实际的平均下载速度(约 60 到 80 Mbps(。但是,在第一次下载后,相邻的下载可能会产生2Gbps,5Gbps甚至无穷大的平均下载速度。我尝试过使用不同的文件大小,但结果几乎相同。这是我用于连续下载测试的代码。

Function SpeedTest()
    Do
        wc.Headers.Add("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0)")
        wc.UseDefaultCredentials = True
        wc.Credentials = New NetworkCredential("admin", "admin")
        wc.DownloadFileAsync(New Uri("file://192.XXX.XX.X/Download_Files/1gb.test"), tmp)
        While wc.IsBusy
            Application.DoEvents()
        End While  
        For i As Integer = 1 To 100
            Thread.Sleep(10)
            Application.DoEvents()
        Next
    Loop Until Toggle1.Checked = False
    Return 0
End Function
Private tmp = IO.Path.Combine(My.Computer.FileSystem.SpecialDirectories.Temp, "1gb.test")

我相信第一个下载的文件是从相邻下载的缓存文件中恢复的。不确定,如果这是真的。(我可以看到 1GB 文件下载在不到一秒钟的时间内完成。但是如果是这样,如何删除缓存文件以产生逼真的下载速度?

经过多次测试,并检查C# WebClient禁用缓存,HttpWebRequest(在我的例子中,FileWebRequest(在控制下载和上传文件方面更有帮助。同样在控制缓冲区大小后,与通过正常方法完成的下载/上传相比,测试得出了更真实的值。此外,在使用 WebClient 时,下载例程的缓冲区大小为 64KB,上载的缓冲区大小为 8KB。为了产生更接近 Windows 下载速度的速率,缓冲区大小必须是文件大小的 1/100。重复下载仍然没有产生相同的结果。但是,如果从第二次尝试开始将缓冲区大小更改为文件大小的 1/1000,则重复下载速率看起来会相似。这是我用于下载的代码。

oRequest = CType(FileWebRequest.Create("file://192.XXX.XX.X/Download_Files/1gb.test"), FileWebRequest)
oRequest.Credentials = New NetworkCredential("admin", "admin")
oResponse = CType(oRequest.GetResponse, WebResponse)
responseStream = oResponse.GetResponseStream()
buffer = New Byte(FileLen(tmp) / 100) {}
fs = New FileStream(tmp, FileMode.Create, FileAccess.Write)
Do
    read = responseStream.Read(buffer, 0, buffer.Length)
    fs.Write(buffer, 0, read)
    Application.DoEvents()
Loop Until read = 0
responseStream.Close()
fs.Flush()
fs.Close()
responseStream.Close()
oResponse.Close()
buffer = Nothing

这应该允许您连续下载文件,并允许切换取消下载

Private sw As New Stopwatch()
Private wc As WebClient
Private tmp = IO.Path.Combine(My.Computer.FileSystem.SpecialDirectories.Temp, "1gb.test")
Private Sub startDownload()
    If wc IsNot Nothing Then
        wc.Dispose()
    End If
    wc = New WebClient()
    wc.Headers.Add("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0)")
    wc.UseDefaultCredentials = True
    wc.Credentials = New NetworkCredential("admin", "admin")
    AddHandler wc.DownloadProgressChanged, AddressOf downloadProgressChanged
    AddHandler wc.DownloadDataCompleted, AddressOf downloadDataCompleted
    sw.Reset()
    sw.Start()
    wc.DownloadFileAsync(New Uri("file://192.XXX.XX.X/Download_Files/1gb.test"), tmp)
End Sub
Private Sub cancelDownload()
    If wc IsNot Nothing AndAlso wc.IsBusy Then
        wc.CancelAsync()
    End If
End Sub
Private Sub Toggle1_CheckedChanged(sender As Object, e As EventArgs) Handles Toggle1.CheckedChanged
    If Toggle1.Checked Then
        startDownload()
    Else
        cancelDownload()
    End If
End Sub
Private Sub downloadProgressChanged(sender As Object, e As DownloadProgressChangedEventArgs)
    Me.Invoke(Sub() Me.Text = e.ProgressPercentage)
End Sub
Private Sub downloadDataCompleted(sender As Object, e As DownloadDataCompletedEventArgs)
    sw.Stop()
    Dim message = If(e.Cancelled, "Operation was cancelled!", "Operation completed!")
    If e.Error IsNot Nothing Then
        message &= Environment.NewLine & "Exception: " & e.Error.Message
    End If
    Dim fi As New FileInfo(tmp)
    Dim sizeInBytes = fi.Length
    Dim durationInSeconds = sw.ElapsedMilliseconds / 1000
    message &= String.Format("Downloaded {0} bytes in {1} seconds ({2} Bps)", sizeInBytes, durationInSeconds, sizeInBytes / durationInSeconds)
    ' do what you want with message, if anything
    If Not e.Cancelled Then
        startDownload()
    End If
End Sub

相关内容

  • 没有找到相关文章

最新更新