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

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

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

  1         /// <summary>
  2         /// 下载并保存文件
  3         /// </summary>
  4         /// <param name="waveID">主键</param>
  5         /// <param name="saveName">文件名</param>
  8         /// <param name="folderName">文件夹名称</param>
  9         /// <param name="speed">限速</param>
 10         /// <param name="callBackMethod">回调</param>
 11         /// <returns></returns>
 12         public int DownloadAndSaveAs(string waveID, string saveName, string folderName, int speed, SetTextCallBack callBackMethod)
 13         {
 14             if (string.IsNullOrWhiteSpace(waveID))
 15                 return -1;
 16
 17             using (WebClient webClient = new WebClient())
 18             {
 19                 try
 20                 {
 21                     string savePath = "C:\\"+ folderName+ "\\";
 22                     if (!Directory.Exists(savePath))
 23                     {
 24                         Directory.CreateDirectory(savePath);
 25                     }
 26                     using (FileStream fs = new FileStream(savePath + saveName, FileMode.Create, FileAccess.Write))
 27                     {
 28                         try
 29                         {
 30                             string url =string.Format(  "Http://www.文件下载路径.com?waveID={0}",waveID);
 31                             HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
 32
 33                             using (var response = (HttpWebResponse)request.GetResponse())
 34                             using (var stream = response.GetResponseStream())
 35                             {
 36                                 int blockSize = 4096;//每次读取的字节数,不固定
 37                                 byte[] buffer = new byte[blockSize];
 38                                 int read = 0;//每次读取后返回的下一次 的坐标位置,当没有数据时是-1
 39                                 long total_read = 0;//已经读取到的字节数总和
 40                                 DateTime begin = DateTime.Now;
 41
 42                                 while ((read = stream.Read(buffer, 0, buffer.Length)) > 0)
 43                                 {
 44                                     total_read += blockSize;
 45                                     double totalSeconds=DateTime.Now.Subtract(begin).TotalSeconds;
 46                                     double byteper = total_read / totalSeconds;//[字节总数]除以[所花时间总秒数]=每秒获取的字节数
 47
 48                                     if (double.IsInfinity(byteper))
 49                                     {
 50                                         //排除byteper正无穷的情况
 51                                         fs.Write(buffer, 0, buffer.Length);
 52                                         continue;
 53                                     }
 54                                     else
 55                                     {
 56                                         double speedPer = byteper / 1024;//单位转换得到千字节
 57                                         if (speedPer >= speed)//speed为我们设置的限速字段,单位kb
 58                                         {
 59                                             //下面的逻辑是通过:现实速度-限速=超速部分,通过超速部分计算要让线程休眠时长。
 60                                             double tempData = speedPer - speed;
 61                                             if (tempData < 1) tempData = 1;
 62                                             int sleepMS = Convert.ToInt32(tempData * (1000 / speed) + 100);//1000除以速度得到“每KB消耗的毫秒数”,100是一个自定义值,更好的限制下载速度
 63                                             if (sleepMS > 1000)
 64                                             {
 65                                                 sleepMS = 1000;//有时下载峰值会超大,导致休眠很长,所以强制设为最多休眠一秒。
 66                                             }
 67                                             else
 68                                             {
 69                                                 if (total_read % 112 == 0)//取模只用于降低重写文本框的频率
 70                                                 {
 71                                                     if (callBackMethod != null)
 72                                                     {
 73                                                         callBackMethod(string.Format("下载速度:{0}KB/s,休眠周期:{1} ms", speedPer.ToString("F"), sleepMS));
 74                                                     }
 75                                                 }
 76                                             }
 77                                             System.Threading.Thread.Sleep(sleepMS);  // 休眠实现限速
 78                                         }
 79                                         else
 80                                         {
 81                                             if (total_read % 198 == 0)
 82                                             {
 83                                                 if (callBackMethod != null)
 84                                                 {
 85                                                     callBackMethod(string.Format("下载速度:{0}KB/s,休眠周期:{1} ms", speedPer.ToString("F"), 0));
 86                                                 }
 87                                             }
 88
 89                                         }
 90                                         fs.Write(buffer, 0, buffer.Length);
 91                                     }
 92                                 }
 93                             }
 94                             return 1;
 95                         }
 96                         catch (Exception e)
 97                         {
 98                             return -1;
 99                         }
100                     }
101                 }
102                 catch (Exception ex)
103                 {
104                     return -1;
105                 }
106             }
107         }

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

转载于:https://www.cnblogs.com/dissun/p/10406398.html

WinForm客户端限速下载(C#限速下载)相关推荐

  1. 百度云获取外链直接下载突破限速

    注意下述方法已无法使用 --------------------------------------------------- 参考来源 https://www.52pojie.cn/forum.ph ...

  2. 百度网盘海外版上传下载不限速;一季度北京平均月薪达11187元;苹果 CEO 增加新候选人|极客头条...

    「极客头条」-- 技术人员的新闻圈! CSDN 的读者朋友们早上好哇,「极客头条」来啦,快来看今天都有哪些值得我们技术人关注的重要新闻吧. 整理 | 梦依丹 出品 | CSDN(ID:CSDNnews ...

  3. 百度云下载不限速方法合集

    PanDownload 使用方法:登录帐号后,将你要下载的文件私密分享出去,然后复制分享链接,这样就可自动下载,并满速下载了.注意:为避免限速请不要在文件列表里右键再单击下载,一定要把文件分享出去,复 ...

  4. 【宅男福利】百度云下载不限速软件,电脑和看视频无广告软件

    百度云下载不限速软件链接: https://pan.baidu.com/s/13TMUtITclfpkcOnF3Sh8Rw 提取码: yxhk 电脑和看视频无广告软件链接: https://pan.b ...

  5. 【推荐】推荐一款云盘 不限速 【下载免登录】【下载不限速】【2T大存储】

    原文:[推荐]推荐一款云盘 不限速 [下载免登录][下载不限速][2T大存储] 推荐一款非常好用的云盘: 新用户注册即可有:2T 容量. 分享:可以不用密码.可以永久使用. 下载:不用登录  ,不用密 ...

  6. [406]百度云下载不限速

    今天给大家带来的是比速盘更快.更强的百度云下载不限速,同样是绿色免安装.无广告.无需登录即可下载,避免了封号的风险.速度比会员都快,会员:你让我情何以堪.. 需要注意的是,今天给大家带来的是浏览器嗅探 ...

  7. 上传下载永不限速之文叔叔

    上传下载永不限速,无论是否登录,上传.下载单个文件最大支持5G,注册送20G云空间 填写我的邀请码:ZTE3KJ,免费领取 5GB 云存储空间(百年).不限速,非常好用! https://wenshu ...

  8. 利用tc和iptables对ftp上传下载进行限速

    概述 可以简单的将iptables理解为虚拟的防火墙,可以完成对封包的过滤.重定向和网络地址的重定向等等功能.tc主要是对流量进行一些的控制.打个比方的话tc就像建立一些限速规则,而iptables可 ...

  9. 百度网盘下载不限速方法

    百度网盘下载不限速方法: -------20230401-------- 使用软件:爱奇艺万能联播 众所周知,爱奇艺是百度旗下的一款产品,所以用爱奇艺万能联播的方法来实现下载百度网盘内容,本质上并没有 ...

  10. 百度网盘海外版Dubox正式更名为TeraBox,上传下载不限速

    百度网盘相信大家都不陌生,在平时的工作与生活中用来存储与分享各类文件那是相当的方便.但是它也有令人恨得牙痒的地方,就是下载太龟速了! 去年,百度旗下公司Popln在海外推出一款网盘产--Dubox,也 ...

最新文章

  1. 接口是什么意思_程序员天天用却不懂得冷知识,这两句口诀,让你理解RESTful接口...
  2. 用 Python 爬了点你们喜欢的小电影
  3. 总线制和多线制示意图_知识||RS485简介及与其他总线网络的区别
  4. CString初始化时提示字符串太大
  5. 数据分类:决策树Decision Tree
  6. Android初级第一讲---Android开发环境的配置
  7. struts2标签处理下拉列表
  8. 如何在ASP.NetCore增加文件上传大小
  9. Algs4-1.4.38 3-sum的初级算法与ThreeSum性能比较
  10. 你真的了解 “开源” 么?请查收【保姆级】开源百科
  11. python编程(paddle ocr)
  12. MATLAB 多行注释
  13. css3 图标效果,css3图标_纯CSS3图标旋转效果代码
  14. 微信小程序--优购商城项目(6)
  15. Unbuntu18.04系统定制化制作与再生龙镜像生成
  16. 思岚科技邀你2017日本东京国际机器人展
  17. java中的BigInteger(很好很强大)(转)
  18. SQLALCHEMY_TRACK_MODIFICATIONS adds significant异常的解决方法
  19. Scratch软件编程等级考试三级——20200319
  20. 刘帅嵌入式系统-BLX(2)

热门文章

  1. LuoguP2756 飞行员配对方案问题(最大流)
  2. 2015年蓝桥杯省赛A组c++第4题
  3. 01《构建之法》阅读笔记01
  4. django上课笔记6-MVC,MTV架构-中间件-初识Form组件
  5. 编译安装squid3.1--亲测
  6. 表达式int('2222',4)的值是多少?(每日一题)
  7. Linux -chattr -隐藏权限(附加权限)
  8. 智慧医疗解决方案可以大大减少医疗资源浪费!
  9. java.lang.Class.isPrimitive()用法解析
  10. 【Qt学习笔记】3.布局