miniftp项目总结(六)

限速
首先定义两个获取系统当前时间的函数:


static struct timeval s_curr_time;
long get_time_sec(void)
{
	if (gettimeofday(&s_curr_time, NULL) < 0) 
	{
		ERR_EXIT("gettimeofday");
	}

	return s_curr_time.tv_sec;
}

long get_time_usec(void)
{
	return s_curr_time.tv_usec;
}

get_time_sec()函数获取系统当前时间的秒数,get_time_usec()函数获取当前系统的微妙数。这里有个little trick,将结构体设置为静态的,获取秒数的时候调用gettimeofday访问结构体,在获取微秒的时候直接访问结构体中的成员。
定义一个睡眠函数,其实内部调用的是系统函数nanosleep:


void nano_sleep(double seconds)
{
	time_t secs = (time_t)seconds;					// 整数部分
	double fractional = seconds - (double)secs;		// 小数部分

	struct timespec ts;
	ts.tv_sec = secs;
	ts.tv_nsec = (long)(fractional * (double)1000000000);
	
	int ret;
	do 
	{
		ret = nanosleep(&ts, &ts);
	}
	while (ret == -1 && errno == EINTR);//条件为真的时候,睡眠剩余的时间会保存在第二个&ts中
	//返回值ret为0的时候,睡眠完成
}

time_t的类型就是long int。
限速函数;

/*
parameters: session_t会话结构体	传输的字节数	上传/下载标志位
return value:void
*/
void limit_rate(session_t *sess, int bytes_transfered, int is_upload)
{
	//数据连接_空闲断开
	sess->data_process = 1;
	//如果配置文件中的上传/下载限速配置为0,直接返回
	if(sess->bw_upload_rate_max==0 && sess->bw_download_rate_max==0)
		return;
	//记录当前时间
	long curr_sec = get_time_sec();
	long curr_usec = get_time_usec();
	//计算传输count个字节的时间
	double elapsed;
	elapsed = (double)(curr_sec - sess->bw_transfer_start_sec);
	elapsed += (double)(curr_usec - sess->bw_transfer_start_usec) / (double)1000000;
	//计算当前传输速率
	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);
	}
	//睡眠
	double 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();	
}

将限速函数,放在上传和下载函数中,读和写的位置之间,即可实现功能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值