预备知识

1.gettimeofday函数

作用:

在C语言中可以使用函数gettimeofday()函数来得到时间。它的精度可以达到微妙。

函数原型:

#include<sys/time.h>

int gettimeofday(struct  timeval*tv,struct  timezone *tz )

返回值:

函数执行成功后返回0,失败后返回-1,错误代码存于errno中。

gettimeofday()会把目前的时间用tv 结构体返回,当地时区的信息则放到tz所指的结构中。

timeval结构体定义为:

struct  timeval{long  tv_sec;/*秒*/long  tv_usec;/*微妙*/
};

timezone结构体定义为:

struct  timezone{int tz_minuteswest;/*和greenwich 时间差了多少分钟*/int tz_dsttime;/*type of DST correction*/
}

注意:

在gettimeofday()函数中tv或者tz都可以为空。如果为空则就不返回其对应的结构体。

2.nanosleep函数

作用:

挂起调用进程/线程的执行,直到至少经过*req中指定的时间,或者传递触发调用线程中处理程序调用或终止进程的信号。

函数原型:

#include <time.h>

int nanosleep(const struct timespec *req, struct timespec *rem);

struct timespec {time_t tv_sec;        /* 秒 */long   tv_nsec;       /* 纳秒 */
};

返回值:

成功休眠所请求的间隔后,返回0。如果调用被信号处理程序中断或遇到错误,则返回-1,并设置errno指示错误。

限速功能的实现

限速的关键是睡眠,如果发现当前传输速度超过最大传输速度就让进程睡眠。

传输速度=传输字节数/传输时间

如果当前传输速度>最大传输速度

则 睡眠时间=(当前传输速度/最大传输速度-1)*当前传输时间

1.传输之前,先获取当前时间的秒数和微秒数并进行记录,每当传输1024字节之后,就判断当前的传输速度

 char buf[1024];//开始传输之前的时间//获取当前时间的秒数和微秒数sess->bw_transfer_start_sec = get_time_sec();sess->bw_transfer_start_usec = get_time_usec();//这是一个循环,所以能实现上传大文件while (1) {//从数据套接字接收数据ret = read(sess->data_fd, buf, sizeof(buf));if (ret == -1) {if (errno == EINTR) {continue;} else {flag = 2;break;}}else if (ret == 0) {flag = 0;break;}//读取了一定数据之后需要判断是否限速limit_rate(sess, ret, 1);//睡醒之后判断是否收到了abor,如果是直接break,其实没有也可以,返回去//的时候read会返回-1,因为已经关闭了数据连接套接字了if (sess->abor_received) {flag = 2;break;}//写入文件中if (writen(fd, buf, ret) != ret) {flag = 1;break;}}

2.判断是否超速,如果超速,进行休眠

当传输了1024字节之后,获取当前时间,通过流过的时间以及在该时间内传输的字节数计算当前的传输速度。

如果没有超过最大传输速度,说明不需要进行休眠限速,但是也要更新时间,以便下次判断。

如果超过最大传输速度,那么计算应该休眠的时间,睡眠时间=(当前传输速度/最大传输速度-1)*当前传输时间,然后进行休眠。

//限速,计算睡眠时间,第二个参数是当前传输的字节数
void limit_rate(session_t *sess, int bytes_transfered, int is_upload)
{//表明处于数据传输的状态sess->data_process = 1;// 睡眠时间=(当前传输速度/最大传输速度-1)*当前传输时间;long curr_sec = get_time_sec();long curr_usec = get_time_usec();//流过的时间,当前所用的传输时间double elapsed;elapsed = (double)(curr_sec - sess->bw_transfer_start_sec);//秒+微秒elapsed += (double)(curr_usec - sess->bw_transfer_start_usec) / (double)1000000;if (elapsed <= (double)0) {//等于0的情况有可能,因为传的太快了elapsed = (double)0.01;}// 计算当前传输速度,传输的量除以传输时间,忽略了传输速度的小数部分unsigned int bw_rate = (unsigned int)((double)bytes_transfered / elapsed);double rate_ratio;//上传if (is_upload) {//当前速度小于上传速度if (bw_rate <= sess->bw_upload_rate_max) {// 不需要限速,也需要更新时间sess->bw_transfer_start_sec = curr_sec;sess->bw_transfer_start_usec = curr_usec;return;}//根据公式进行计算rate_ratio = bw_rate / sess->bw_upload_rate_max;}//下载else {if (bw_rate <= sess->bw_download_rate_max) {//不需要限速 sess->bw_transfer_start_sec = curr_sec;sess->bw_transfer_start_usec = curr_usec;return;}rate_ratio = bw_rate / sess->bw_download_rate_max;}//计算睡眠时间//睡眠时间=(当前传输速度/最大传输速度-1)*当前传输时间��;double pause_time;//需要睡眠的时间pause_time = (rate_ratio - (double)1) * elapsed;//进行睡眠nano_sleep(pause_time);//更新时间,下一次要开始传输的时间更新为当前时间sess->bw_transfer_start_sec = get_time_sec();sess->bw_transfer_start_usec = get_time_usec();}

休眠函数的选择

sleep函数中有说明:

而我们在空闲断开中会使用alarm函数,所以这里就不选择sleep函数,而是选择nanosleep函数。

如何实现限制上传或下载速度相关推荐

  1. 家用宽带的上传和下载速度

    1. ADSL 上传速度对下载的影响 有试验证明,当上传满载时,下载速度讲变为理想速度的40%. --------------------------------------------------- ...

  2. 使用speedtest-cli进行服务器上传和下载速度测试

    speedtest-cli是一个简单而强大的命令行工具,可以帮助我们方便地测试服务器的上传和下载速度.本文将介绍如何使用speedtest-cli进行服务器速度测试. 步骤1. 下载speedtest ...

  3. 如何在Mac上测试宽带的网速(上传和下载速度)和网络质量

    在mac电脑上怎么测试网速有多快?在使用mac电脑时,想测试一下自己的网络下载速度,或上传速度时,怎么测速?一起来看看吧. 有时我们新安装了宽带后,比如100M.200M甚至千兆的宽带,想要检测下宽带 ...

  4. 阿里云盘上传与下载速度实测

    目录 前言:百度网盘之痛 一.阿里云盘介绍 1.1 手机版 1.2 网页版 1.3 电脑版 二.上传测试 2.1 上传自己的文件,2.5-3M/s 2.2 上传网络资源,不分大小,秒传 三.下载测试 ...

  5. 为什么上传速度比下载速度慢

    很多误解都是因为不了解才产生的,我从技术上来讲一下为什么用户级宽带下行的带宽要远远比上行带宽大. 首先从用户行为而言,下载应用要远大于上传应用,这就导致上下行带宽一致下,大量的上行带宽被浪费,所以上行 ...

  6. 阿里云服务器上传下载速度的测评

    阿里云服务器上传/下载速度如何测试,使用Speedtest带宽测试工具来测试一下阿里云服务器上传和下载速度,阿里云百科以阿里云中国香港地域2核4G1M带宽服务器为例,阿小云来测试一下阿里云服务器实际的 ...

  7. 七牛图片上传的使用心得[PHP篇]

    曾写过一篇文章随便写了写我怎么用七牛的,发现很多小伙伴来问我,这回写个详细的. 前提: 1.已经有七牛账号,创建了空间,能看到AccessKey/SecretKey: 2.你知道怎么用composer ...

  8. Linux 下使用Trickle限制下载/上传带宽

    你有没有遇到过一个程序占用了你所有的网络带宽的情况?如果你遇到过,那么你就需要限制带宽的应用.不管你是一个系统管理员还是一名普通Linux用户,您都应该学习如何控制应用的上传和下载速度来确保你的网络带 ...

  9. 电脑上传网速怎么测试软件,宽带上传速度怎么测试 教你如何看电脑宽带上传速度...

    网速一般分为下载速度和上传速度,一般我们测算网速只是测试下载速度,只要电脑从网上下载速度快,用户通常比较满意.但你知道吗?上传速度也是值得关注的,尤其是在云网络时代,很多朋友都要传文件到网盘或者视频网 ...

最新文章

  1. es5 温故而知新 创建私有成员、私有变量、特权变量的方法
  2. python是不是特别垃圾-深度解析Python垃圾回收机制(超级详细)
  3. TIOBE 2011年7月编程语言排行榜:Objective-C成为年度语言
  4. springboot中的mybatis是如果使用pagehelper的
  5. 使用CSS属性处理前端开发中长文本造成的内容显示重叠问题
  6. matlab 列表 剪切,利用Matlab进行文件批量复制、剪切和修改文件名
  7. 大数据2019年的三大趋势你看了吗?
  8. 计算机技术在农机上的应用,计算机视觉技术在农机自动化上的应用与优势分析.pdf...
  9. Spring—使用类加载从配置文件中读取配置
  10. 在虚幻引擎5中构建你的首款游戏 - 03 - 模型和材质蓝图
  11. SDHC卡与SD卡的区别究竟在哪?
  12. 【EXLIBRIS】#小词旮旯# 004 Camera
  13. 信息可视化中的重要准则——以扇贝单词app中的可视化为例
  14. 2011年国外最受欢迎的15个电影网站
  15. javaScript中的特殊字符
  16. 软件工程网络15个人案例作业3(201521123045 郑子熙)
  17. 微商城支付开发(二)
  18. python语言设计二级教程答案2019_全国计算机等级考试二级教程2019年版——Python语言程序设计参考答案...
  19. 电销卡在哪里办理,有用过的没
  20. python中的self

热门文章

  1. MaxCompute SQL示例解析
  2. POJ 3422 Kaka's Matrix Travels | 费用流
  3. 探寻维纳控制论密码,解读“人工智能”各大学派
  4. 【鱼眼】M4/3用户对鱼眼镜头的误解(7.5mm的鱼眼镜头的等效焦距是12mm或15mm,但是依然是鱼眼镜头而不是广角镜头)
  5. 基因工程-3-基因工程载体
  6. 解决MySQL导入.CSV数据中文乱码
  7. 大数据技术背景介绍(开号篇)
  8. OC中,类的基础知识
  9. 基于设备指纹零感验证系统
  10. html提取正文,网页正文提取工具Readability