最近由于工作需要,需要开发一个能把服务器上的文件批量下载下来本地保存,关键是要实现限速下载,如果全速下载会影响服务器上的带宽流量。本来我最开始的想法是在服务器端开发一个可以从源头就限速下载的Api端口,可是找了半天没有相关的实现代码,后来好不容易找到一个,却只能只能在WebForm的HttpResponse上实现,我用的是webApi的HttpResponseMessage实现不了把流文件一点一点输出。(可能是我对相关协议还不清楚,所以把参考链接给出,如果有知道怎么在WebApi框架服务器端限速下载的童鞋,麻烦告诉我一下:https://www.cnblogs.com/ghd258/articles/260236.html)

  后来没办法,把思路改为直接在下载的客户端限制下载速度,主体思路就是每下载N字节后就计算平均下载速度,如果平均下载速度快了,就暂停下载,通过拉长下载时间来实现降低平均下载速度。下面贴出主要核心的下载代码:

  欢迎批评指正,写的比较匆忙!

         /// <summary>
/// 下载并保存文件
/// </summary>
/// <param name="waveID">主键</param>
/// <param name="saveName">文件名</param>
/// <param name="folderName">文件夹名称</param>
/// <param name="speed">限速</param>
/// <param name="callBackMethod">回调</param>
/// <returns></returns>
public int DownloadAndSaveAs(string waveID, string saveName, string folderName, int speed, SetTextCallBack callBackMethod)
{
if (string.IsNullOrWhiteSpace(waveID))
return -; using (WebClient webClient = new WebClient())
{
try
{
string savePath = "C:\\"+ folderName+ "\\";
if (!Directory.Exists(savePath))
{
Directory.CreateDirectory(savePath);
}
using (FileStream fs = new FileStream(savePath + saveName, FileMode.Create, FileAccess.Write))
{
try
{
string url =string.Format( "Http://www.文件下载路径.com?waveID={0}",waveID);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); using (var response = (HttpWebResponse)request.GetResponse())
using (var stream = response.GetResponseStream())
{
int blockSize = ;//每次读取的字节数,不固定
byte[] buffer = new byte[blockSize];
int read = ;//每次读取后返回的下一次 的坐标位置,当没有数据时是-1
long total_read = ;//已经读取到的字节数总和
DateTime begin = DateTime.Now; while ((read = stream.Read(buffer, , buffer.Length)) > )
{
total_read += blockSize;
double totalSeconds=DateTime.Now.Subtract(begin).TotalSeconds;
double byteper = total_read / totalSeconds;//[字节总数]除以[所花时间总秒数]=每秒获取的字节数 if (double.IsInfinity(byteper))
{
//排除byteper正无穷的情况
fs.Write(buffer, , buffer.Length);
continue;
}
else
{
double speedPer = byteper / ;//单位转换得到千字节
if (speedPer >= speed)//speed为我们设置的限速字段,单位kb
{
//下面的逻辑是通过:现实速度-限速=超速部分,通过超速部分计算要让线程休眠时长。
double tempData = speedPer - speed;
if (tempData < ) tempData = ;
int sleepMS = Convert.ToInt32(tempData * ( / speed) + );//1000除以速度得到“每KB消耗的毫秒数”,100是一个自定义值,更好的限制下载速度
if (sleepMS > )
{
sleepMS = ;//有时下载峰值会超大,导致休眠很长,所以强制设为最多休眠一秒。
}
else
{
if (total_read % == )//取模只用于降低重写文本框的频率
{
if (callBackMethod != null)
{
callBackMethod(string.Format("下载速度:{0}KB/s,休眠周期:{1} ms", speedPer.ToString("F"), sleepMS));
}
}
}
System.Threading.Thread.Sleep(sleepMS); // 休眠实现限速
}
else
{
if (total_read % == )
{
if (callBackMethod != null)
{
callBackMethod(string.Format("下载速度:{0}KB/s,休眠周期:{1} ms", speedPer.ToString("F"), ));
}
} }
fs.Write(buffer, , buffer.Length);
}
}
}
return ;
}
catch (Exception e)
{
return -;
}
}
}
catch (Exception ex)
{
return -;
}
}
}

本文参考了,但做了优化:http://blog.useasp.net/archive/2016/03/10/limit-download-speed-in-dotnet-httpwebresponse.aspx

WinForm客户端限速下载(C#限速下载)的更多相关文章

  1. 01_基于TCP的循环为同一个客户端下载文件的下载器

    原版: TCP分为客户端(client)和服务器(server),每次服务器只能为客户端提供一次的下载服务. 改良版: TCP分为客户端(client)和服务器(server), (1)每次服务器能为 ...

  2. Oracle数据库访问客户端 sqldeveloper-18.4.0-376.1900-x64 下载

    Oracle数据库访问客户端 sqldeveloper-18.4.0-376.1900-x64 下载地址:https://pan.baidu.com/s/1RnHVuMcCNZQ7ncHLKDJ33Q

  3. C# winform带进度条的图片下载

    代码如下: public partial class FrmMain : Form { public FrmMain() { InitializeComponent(); } private void ...

  4. 基于服务(Web Service)的文件管理Winform客户端实现(二)

    上一篇主要介绍文件管理服务有哪些方法,实现了哪些功能. 基于服务(Web Service)的文件管理Winform客户端实现(一) 本篇将根据文件服务服务实现Winform客户端设计.开发. 3.   ...

  5. 百度网盘快速下载工具下载:Pandownload下载

    众所周知的百度网盘下载限速很厉害,所以就有了快速下载工具出现了.一般情况下,按照家里网速有多快,使用工具下载就有多快. 可以直接复制如下图进行下载: 另外,PanDownload[百度网盘下载工具]无 ...

  6. windows 10最新版镜像资源下载 Win10 ISO下载教程

    最近发现原创写的文章被无良爬走,而且变成了无图尬文,所以开头附上原文地址: http://www.cnblogs.com/xueyudlut/p/7497975.html -------------- ...

  7. MVC还是MVVM?或许VMVC更适合WinForm客户端

    最近开始重构一个稍嫌古老的C/S项目,原先采用的技术栈是『WinForm』+『WCF』+『EF』.相对于现在铺天盖地的B/S架构来说,看上去似乎和Win95一样古老,很多新入行的,可能就没有见过经典的 ...

  8. winform客户端利用webClient实现与Web服务端的数据传输

    由于项目需要,最近研究了下WebClient的数据传输.关于WebClient介绍网上有很多详细介绍,大概就是利用WebClient可以实现对Internet资源的访问.无外乎客户端发送请求,服务端处 ...

  9. winform客户端程序第一次调用webservice方法很慢的解决方法

    .net2.0的winform客户端最常用的与服务端通信方式是通过webservice,最近在用dottrace对客户端做性能测试的时候发现,客户端程序启动以后,第一次调用某一个webservice的 ...

  10. 人工智能大数据,公开的海量数据集下载,ImageNet数据集下载,数据挖掘机器学习数据集下载

    人工智能大数据,公开的海量数据集下载,ImageNet数据集下载,数据挖掘机器学习数据集下载 ImageNet挑战赛中超越人类的计算机视觉系统微软亚洲研究院视觉计算组基于深度卷积神经网络(CNN)的计 ...

随机推荐

  1. Ubuntu下安装mysql与mysql workbench

    Ubuntu 安装jdk:[链接] Ubuntu安装eclipse:[链接] Ubuntu下安装MySQL与mysql workbench:[链接] Ubuntu配置tomcat9:[链接] 1.su ...

  2. solr6.6 导入索引数据

    1.什么是core core是solr的一个索引库,可以理解为一个数据库,core可以根据需要,创建多个. 2.创建core 例如,创建一个core,名字叫mycore,就可以用一下命令: E:\so ...

  3. 书籍推荐Python编程:从入门到实践(高清完整pdf)

    这本书我看了电子版的,感觉还不错,全书共有20章,书中的简介如下: 本书旨在让你尽快学会 Python ,以便能够编写能正确运行的程序 -- 游戏.数据可视化和 Web 应用程序,同时掌握让你终身受益 ...

  4. DDD「领域驱动设计」分层架构初探

    前言 基于 DDD 传统分层架构实现. 项目 github地址:https://github.com/WuMortal/DDDSample 这个分层架构是工作中项目正在使用的分层架构,使用了一段时间发 ...

  5. Detours HOOK 库 过滤LoadLibraryExW

    Detours HOOK 库 Hook 过滤LoadLibraryExW 一丶简介 1.1 Detours库简介 Detours是微软提供的HOOK库.为我们Hook提供了方便.再也不用手撸 HOOK ...

  6. 【原】javascript笔记之this用法

    javascript中的this学习起来相对复杂,最近花了点时间研究,总结起来大概这只有5种情况,相信只要熟悉这5种用法,基本是可以解决所有的this问题,文本不介绍this设计原理,只介绍用法,阅读 ...

  7. Python爬虫使用lxml模块爬取豆瓣读书排行榜并分析

    上次使用了BeautifulSoup库爬取电影排行榜,爬取相对来说有点麻烦,爬取的速度也较慢.本次使用的lxml库,我个人是最喜欢的,爬取的语法很简单,爬取速度也快. 本次爬取的豆瓣书籍排行榜的首页地 ...

  8. Netty源码—五、内存分配概述

    Netty中的内存管理应该是借鉴了FreeBSD内存管理的思想--jemalloc.Netty内存分配过程中总体遵循以下规则: 优先从缓存中分配 如果缓存中没有的话,从内存池看看有没有剩余可用的 如果 ...

  9. 腾讯视频国际版(Android)电量测试方法研究与总结

    本文由云+社区发表 作者:腾讯移动品质中心TMQ 1.研究背景: 在2017年Google I/O大会上,Google发布了Google Play管理中心的新功能:Android vitals.当ap ...

  10. Oracle 经典面试题

    第一题 create table test( id ) primary key, type ) , t_id ), value ) ); ,,,'张三'); ,,,'男'); ,,,'); ,,,'刘 ...