WinForm客户端限速下载(C#限速下载)
最近由于工作需要,需要开发一个能把服务器上的文件批量下载下来本地保存,关键是要实现限速下载,如果全速下载会影响服务器上的带宽流量。本来我最开始的想法是在服务器端开发一个可以从源头就限速下载的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#限速下载)的更多相关文章
- 01_基于TCP的循环为同一个客户端下载文件的下载器
原版: TCP分为客户端(client)和服务器(server),每次服务器只能为客户端提供一次的下载服务. 改良版: TCP分为客户端(client)和服务器(server), (1)每次服务器能为 ...
- Oracle数据库访问客户端 sqldeveloper-18.4.0-376.1900-x64 下载
Oracle数据库访问客户端 sqldeveloper-18.4.0-376.1900-x64 下载地址:https://pan.baidu.com/s/1RnHVuMcCNZQ7ncHLKDJ33Q
- C# winform带进度条的图片下载
代码如下: public partial class FrmMain : Form { public FrmMain() { InitializeComponent(); } private void ...
- 基于服务(Web Service)的文件管理Winform客户端实现(二)
上一篇主要介绍文件管理服务有哪些方法,实现了哪些功能. 基于服务(Web Service)的文件管理Winform客户端实现(一) 本篇将根据文件服务服务实现Winform客户端设计.开发. 3. ...
- 百度网盘快速下载工具下载:Pandownload下载
众所周知的百度网盘下载限速很厉害,所以就有了快速下载工具出现了.一般情况下,按照家里网速有多快,使用工具下载就有多快. 可以直接复制如下图进行下载: 另外,PanDownload[百度网盘下载工具]无 ...
- windows 10最新版镜像资源下载 Win10 ISO下载教程
最近发现原创写的文章被无良爬走,而且变成了无图尬文,所以开头附上原文地址: http://www.cnblogs.com/xueyudlut/p/7497975.html -------------- ...
- MVC还是MVVM?或许VMVC更适合WinForm客户端
最近开始重构一个稍嫌古老的C/S项目,原先采用的技术栈是『WinForm』+『WCF』+『EF』.相对于现在铺天盖地的B/S架构来说,看上去似乎和Win95一样古老,很多新入行的,可能就没有见过经典的 ...
- winform客户端利用webClient实现与Web服务端的数据传输
由于项目需要,最近研究了下WebClient的数据传输.关于WebClient介绍网上有很多详细介绍,大概就是利用WebClient可以实现对Internet资源的访问.无外乎客户端发送请求,服务端处 ...
- winform客户端程序第一次调用webservice方法很慢的解决方法
.net2.0的winform客户端最常用的与服务端通信方式是通过webservice,最近在用dottrace对客户端做性能测试的时候发现,客户端程序启动以后,第一次调用某一个webservice的 ...
- 人工智能大数据,公开的海量数据集下载,ImageNet数据集下载,数据挖掘机器学习数据集下载
人工智能大数据,公开的海量数据集下载,ImageNet数据集下载,数据挖掘机器学习数据集下载 ImageNet挑战赛中超越人类的计算机视觉系统微软亚洲研究院视觉计算组基于深度卷积神经网络(CNN)的计 ...
随机推荐
- js多个元素随机且不重叠分布在页面中
最近,公司要做一个类似挖矿的项目,大概其是当用户登录进入首页后,如果用户有已经生成的原力值,则在其点击原力值后可以类似蚂蚁森林那样收集原力值,当用户将所有的原力值收集完毕后开始提醒用户新的原力值正在生 ...
- Postman----设置代理抓取手机上的请求
一般为方便接口测试,我们都会设置代理,抓取手机上的请求来方便测试,具体的操作方法如下. 操作步骤: 一.手机和电脑连接同一网络,查看电脑连接网络的IP,配置手机的代理 1.查看电脑连接的网络与IP地址 ...
- LaTeX 公式编辑
推荐一篇关于LaTeX的文档:<一份不太简短的LATEX 2ε介绍> 1. 常用数学公式符号: 求期望 $\mathbb{E}$ \mathbb{E} 正负无穷 $+\infty$,$-\ ...
- 图解Java线程的生命周期,看完再也不怕面试官问了
文章首发自个人微信公众号: 小哈学Java https://www.exception.site/java-concurrency/java-concurrency-thread-life-cycle ...
- python接口自动化(十五)--参数关联接口(详解)
简介 我们用自动化新建任务之后,要想接着对这个新建任务操作,那就需要用参数关联了,新建任务之后会有一个任务的Jenkins-Crumb,获取到这个Jenkins-Crumb,就可以通过传这个任务Jen ...
- MySQL 复制 - 性能与扩展性的基石 4:主备切换
一旦使用 MySQL 的复制功能,就很大可能会碰到主备切换的情况.也许是为了迭代升级服务器,或者是主库出现问题时,将一台备库转换成主库,或者只是希望重新分配容量.不过出于什么原因,都需要将新主库的信息 ...
- Unable to start embedded container; nested exception is org.springframework.context.ApplicationContextException: Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFa
Springboot通过application启动报错 2019-01-25 14:02:33.810 ERROR [restartedMain] org.springframework.boot.S ...
- 使用WebGL 自定义 3D 摄像头监控模型
前言 随着视频监控联网系统的不断普及和发展, 网络摄像机更多的应用于监控系统中,尤其是高清时代的来临,更加快了网络摄像机的发展和应用. 在监控摄像机数量的不断庞大的同时,在监控系统中面临着严峻的现状问 ...
- 深入理解Linux内核 学习笔记(4)
第四章 中断和异常 中断通常被分为同步中断和异步中断,同步中断是当指令执行时由CPU控制单元产生的,之所以称为同步,是因为只有在一条指令终止执行后CPU才会发出中断异步中断是由其他硬件设备依照CPU时 ...
- 教程:关于如何通过Maven仓库安装Spire系列的 Java产品
Spire系列库中已发布的Java产品目前有三个,即Spire.PDF for Java.Spire.Presentation for Java.Spire.Barcode for Java.使用该J ...