
将你的 scp 会话的最大上传带宽设定为 100 KB/s:
$ trickle -u 100 scp backup.tgz alice@remote_host.com:
另一种控制你的带宽资源的方式是在每一个接口上限制带宽。这在你与其他人分享你的网络连接的上行带宽时尤为实用。同其他一样,Linux 有一个工具来为你做这件事。wondershaper就是干这个的。
wondershaper 实际上是一个 shell 脚本,它使用 tc 来定义流量调整命令,使用 QoS 来处理特定的网络接口。外发流量通过放在不同优先级的队列中,达到限制传出流量速率的目的;而传入流量通过丢包的方式来达到速率限制的目的。
举个例子, 将 eth0 的最大下载/上传带宽分别设定为 1000Kbit/s 和 500Kbit/s:
$ sudo wondershaper <interface><download-rate><upload-rate>
关于代码实现,首先要说的是在帧的接收和发送的时候都讲到了qos. 在实际的应用中发送用的最多,而接收的控制需要其他辅助性的工作. linux下qos需要iproute2集成的tc命令,以及iptables命令等的支持和配合,它和iptables/netfilters有点类似都需要用户空间和内核空间的配合.QOS的控制分为Ingress 和Egress。这里主要分析出口.
调试需要iproute2的tc :
点击(此处)折叠或打开
Linux Traffic Control is configured with the utility tc. It is part of the iproute2 package. Some Linux distributions already include tc, but it may be an old version, without support for Diffserv.
点击(此处)折叠或打开
调试版本iproute2-4.2.0
那么编译iproute2需要依赖的东西:
Bison
Flex
Libdb-dev
找到tc的源码后,我们先看看tc命令的主程序 tc.c
点击(此处)折叠或打开
int main(int argc, char **argv)
{
int ret
char *batch_file = NULL
while (argc >1) {
if (argv[1][0] != '-')
break
if (matches(argv[1], "-stats") == 0 ||
matches(argv[1], "-statistics") == 0) {
++show_stats
} else if (matches(argv[1], "-details") == 0) {
++show_details
} else if (matches(argv[1], "-raw") == 0) {
++show_raw
} else if (matches(argv[1], "-pretty") == 0) {
++show_pretty
} else if (matches(argv[1], "-graph") == 0) {
show_graph = 1
} else if (matches(argv[1], "-Version") == 0) {
printf("tc utility, iproute2-ss%s\n", SNAPSHOT)
return 0
} else if (matches(argv[1], "-iec") == 0) {
++use_iec
} else if (matches(argv[1], "-help") == 0) {
usage()
return 0
} else if (matches(argv[1], "-force") == 0) {
++force
} else if (matches(argv[1], "-batch") == 0) {
argc-- argv++
if (argc <= 1)
usage()
batch_file = argv[1]
} else if (matches(argv[1], "-netns") == 0) {
NEXT_ARG()
if (netns_switch(argv[1]))
return -1
} else if (matches(argv[1], "-names") == 0 ||
matches(argv[1], "-nm") == 0) {
use_names = true
} else if (matches(argv[1], "-cf") == 0 ||
matches(argv[1], "-conf") == 0) {
NEXT_ARG()
conf_file = argv[1]
} else {
fprintf(stderr, "Option \"%s\" is unknown, try \"tc -help\".\n", argv[1])
return -1
}
argc-- argv++
}
if (batch_file)
return batch(batch_file)
if (argc <= 1) {
usage()
return 0
}
tc_core_init()
if (rtnl_open(&rth, 0) <0) {
fprintf(stderr, "Cannot open rtnetlink\n")
exit(1)
}
if (use_names &&cls_names_init(conf_file)) {
ret = -1
goto Exit
}
ret = do_cmd(argc-1, argv+1)
Exit:
rtnl_close(&rth)
if (use_names)
cls_names_uninit()
return ret
}
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)