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

    STM32标准库GPIO操作 STM32任何外围设备的使用都分为两部分:初始化和使用.体现在代码上就是:(1)有一个初始化函数(2)main函数中的使用 1.初始化GPIO 初始化GPIO函数代码: ...

  2. php SESSION入库的实现

    session入库,就是重写session制机,在session的周期内,获得到session的数据并记录到数据库 Session默认是存放到服务器上的文件中,不方便管理,如果能把session存放到 ...

  3. Mybatis:缓存,动态SQL,注解SQL以及动态标签使用

    1 转义字符 字符 转义 描述 < < 小于 <= <= 小于等于 > > 大于 >= >= 大于等于 <> <> 不等于 &a ...

  4. .NET 平台上C#语言的基本技术点

    第一次用画图3D画的知识点,有点丑..........开始Csharp之路

  5. Spring Boot入门(三):使用Scheduled注解实现定时任务

    在程序开发的过程中,经常会使用定时任务来实现一些功能,比如: 系统依赖于外部系统的非核心数据,可以定时同步 系统内部一些非核心数据的统计计算,可以定时计算 系统内部的一些接口,需要间隔几分钟或者几秒执 ...

  6. 设计模式 | 抽象工厂模式(abstract factory)

    定义: 提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们具体的类. 结构:(书中图,侵删) 这个图相对来说有一点点复杂,其实就是在工厂方法模式的基础上做了一些扩展,工厂方法模式只用于生成一种 ...

  7. Genymotion Android模拟器Genymotion的安装和使用

    Android模拟器Genymotion的安装和使用 by:授客 QQ:1033553122 环境: Win7 Genymotion 2.12.0 下载地址:http://download.canad ...

  8. 2018-09-13 代码翻译尝试-使用Roaster解析和生成Java源码

    此文是前文使用现有在线翻译服务进行代码翻译的体验的编程语言方面第二点的一个尝试. 参考Which framework to generate source code ? - Cleancode and ...

  9. NSTimer循环引用的几种解决方案

    前言 在iOS中,NSTimer的使用是非常频繁的,但是NSTimer在使用中需要注意,避免循环引用的问题.之前经常这样写: - (void)setupTimer { self.timer = [NS ...

  10. git工具使用说明

    一.什么是git?     Git是分布式版本控制系统      概念: 工作区:就是你在电脑里能看到的目录: 暂存区:一般存放在(.git/index)中,所以我们把暂存区有时也叫作索引(index ...