参考资料
tc的参数说明https://linux.die.net/man/8/tc
tc的小demo(推荐必读)https://wiki.archlinux.org/index.php/advanced_traffic_control#Stochastic_Fairness_Queueing_(SFQ)
控制代码
1. tc qdisc del root dev em4
2. tc qdisc add dev em4 root handle 1: htb default 30
3. tc class add dev em4 parent 1: classid 1:20 htb rate 5mbit ceil 5mbit
4. tc qdisc add dev em4 parent 1:20 handle 20: sfq perturb 10
5. tc class add dev em4 parent 1:1 classid 1:30 htb rate 1000mbit
6. tc qdisc add dev em4 parent 1:30 handle 30: sfq perturb 10
7. tc filter add dev em4 protocol ip parent 1: prio 1 u32 match ip dport 10990 0xffff flowid 1:20
代码解释
1. 删除网卡em4上现有的所有规则
2.This line sets a HTB qdisc on the root of em4, and it specifies that the class 1:20 is used by default. It sets the name of the root as 1:, for future references.
在网卡em4上添加一个名字为1:的root HTB qdisc
3. 在root qdisc下创建一个分支1:20,这个分支的带宽固定为5mbit/s
4. 在分支1:20下创建一个classless 的 sfq qdisc,该队列可以随机的发送其内部存放的packet,perturb 10表示该对队列每间隔10s更新一下自身的hash算法。这个随机算法能较为公平的发送其内部的数据包。
5. 在root qdisc下创建一个分支1:30,这个分支的带宽为5mbit/s
6. 在分支1:30下创建一个classless 的 sfq qdisc,记为30
7. 在root队列上添加filter,该filter将所有目的端口为10990的包,都存放到了分支1:20下,剩余的默认存放到1:30下。
通过上述代码可以让所有发往端口10990的包的发送速度控制在 tc的速度限定值(5mbits/s)/用户数
效果展示
('user', 4, ' ith', 97, 1, 'speed', 0.9886388595896279, 'Mbit/s')
('user', 3, ' ith', 98, 1, 'speed', 0.9768347549029545, 'Mbit/s')
('user', 0, ' ith', 97, 1, 'speed', 0.9709888630232459, 'Mbit/s')
('user', 2, ' ith', 95, 1, 'speed', 0.9694382003856689, 'Mbit/s')
('user', 1, ' ith', 98, 1, 'speed', 0.9450305863094577, 'Mbit/s')
开启5个不同的进程,即为user0到user4,向端口10990发送数据并统计发送速度,由上述实验效果可知,5个用户均分了5Mbit/s的带宽。
注意事项:
1.分析客户端发送速度
for i in range(100):
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
client.connect((gpu01_ip, gpu01_port))
a = time.time()
data = client.send(bytes("*"*102400))
b = time.time()
print("user", user_num, " ith", i,1,"speed",data*8.0/1024/1024/(b-a),"Mbit/s")
client.close()
2.服务端数据接收方法
ADDR = ("192.168.1.16", 10990)
listen_sock = socket.socket()
# listen_sock.settimeout(5.0) #设定超时时间后,socket其实内部变成了非阻塞,但有一个超时时间
listen_sock.bind(ADDR)
listen_sock.listen(20)
while True:
try:
conn, addr = listen_sock.accept()
while True:
a = time.time()
data = conn.recv(102400)
b = time.time()
if len(data)==0:
break
else:
print("length",len(data),"period",b-a,"speed",len(data)*8/1024/1024/(b-a),"Mbit/s")
3. 有很多现成的工具可以监控网络的收发包速率,推荐使用nload,高端大气上档次。如果只是想单独的测试端口之间的带宽,推荐使用iperf3,具体测试方法如下:
服务器端:iperf3 -s -p 10990
客户端:iperf3 -c 192.168.1.16 -p 10990