• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

WinForm客户端限速下载(C#限速下载)

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

  最近由于工作需要,需要开发一个能把服务器上的文件批量下载下来本地保存,关键是要实现限速下载,如果全速下载会影响服务器上的带宽流量。本来我最开始的想法是在服务器端开发一个可以从源头就限速下载的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


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
C#获取字符串生成图片后的长度发布时间:2022-07-10
下一篇:
C#記錄程序運行時間发布时间:2022-07-10
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap