当前位置:网站首页>change the available bandwidth of tcp flow dynamically in mininet
change the available bandwidth of tcp flow dynamically in mininet
2022-08-02 14:12:00 【Soonyang Zhang】
I want to make a tcp sender probe dynamically available bandwidth during the session. Previously, I tried to change the bandwidth of net device directly with the help of tc [1]. But the reusults are not conforming to my expection.
So ,in this post, such goal is achieved by adding background possion flow.
Here is my code.
udp_possion.cc. The sending rate is changed every 10 seconds. No receiver is needed.
/*
Client side implementation of UDP client-server model
https://www.geeksforgeeks.org/udp-server-client-implementation-c/
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <stdbool.h>
#include <chrono>
#include <time.h>
#include <math.h>
#include <signal.h>
#include <stdlib.h> //RAND_MAX
#include <iostream>
int make_nonblocking (int fd){
int flags, ret;
flags = fcntl(fd, F_GETFL, 0);
if (flags == -1) {
return -1;
}
// Set the nonblocking flag.
flags |= O_NONBLOCK;
ret = fcntl(fd, F_SETFL, flags);
if (ret == -1) {
return -1;
}
return 0;
}
int64_t WallTimeNowInUsec(){
std::chrono::system_clock::duration d = std::chrono::system_clock::now().time_since_epoch();
std::chrono::microseconds mic = std::chrono::duration_cast<std::chrono::microseconds>(d);
return mic.count();
}
int64_t TimeMillis(){
return WallTimeNowInUsec()/1000;
}
double e_random(double lambda){
double ret=0.0;
double u=0.0;
do{
u=(double)rand()/(double)RAND_MAX;;
}while(u<=0||u>1);
ret=(-1.0/lambda)*log(u);
return ret;
}
static volatile bool running=true;
void signal_exit_handler(int sig)
{
running=false;
}
const int kBufferSize=1500; int rate_table[]={2000000,4000000,6000000};
const int64_t rate_duration=10000000;// 10s
int main(int argc, char **argv) {
signal(SIGTERM, signal_exit_handler);
signal(SIGINT, signal_exit_handler);
signal(SIGTSTP, signal_exit_handler);
if (argc != 3) {
fprintf(stderr, "Usage: %s hostname port\n", argv[0]);
exit(1);
}
srand((unsigned)time(NULL));
uint16_t port= 1234;
char buffer[kBufferSize];
char *server_ip=argv[1];
port = (uint16_t)atoi(argv[2]);
int sockfd;
struct sockaddr_in servaddr;
if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
memset(&servaddr, 0, sizeof(servaddr));
// Filling server information
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(port);
servaddr.sin_addr.s_addr = inet_addr(server_ip);
int64_t next_send_time=0;
int offset=0;
int bps=rate_table[offset];
int packet_size=1450;
double interval=0.0;
double lambda=0.0;
int all=sizeof(rate_table)/sizeof(rate_table[0]);
int64_t next_rate_time=0;
while(running){
int64_t now=WallTimeNowInUsec();
if(next_rate_time==0||now>=next_rate_time){
bps=rate_table[offset];
interval=((double)packet_size*8*1000)/(bps);
lambda=1.0/interval;
offset=(offset+1)%all;
next_rate_time=now+rate_duration;
}
if(next_send_time==0||now>=next_send_time){
sendto(sockfd, (const char *)buffer, packet_size,
0,(const struct sockaddr *)&servaddr,sizeof(servaddr));
int64_t micro_ts=e_random(lambda)*1000;
next_send_time=now+micro_ts;
}
}
close(sockfd);
return 0;
}
Build it: g++ -o possion_sender udp_possion.cc
The tested topology in mininet.
tcp-possion-topo.py
#!/usr/bin/python
import time
import sys
import os
import threading
import subprocess
import signal
from mininet.cli import CLI
from mininet.log import lg, info
from mininet.node import Node
from mininet.util import quietRun
from mininet.net import Mininet
from mininet.link import TCLink
from mininet.link import Intf
from mininet.node import OVSSwitch,Node
'''
'''
if __name__ == '__main__':
bottleneckbw=10
nonbottlebw=500;
rtt=40*3/2
buffer_size =bottleneckbw*1000*rtt/(1500*8)
net = Mininet( cleanup=True )
h1 = net.addHost('h1',ip='10.0.0.1')
h2 = net.addHost('h2',ip='10.0.0.2')
s1 = net.addSwitch( 's1' )
c0 = net.addController('c0')
net.addLink(h1,s1,intfName1='h1-eth0',intfName2='s1-eth0',cls=TCLink , bw=nonbottlebw, delay='10ms', max_queue_size=10*buffer_size)
net.addLink(s1,h2,intfName1='s1-eth1',intfName2='h2-eth0',cls=TCLink , bw=bottleneckbw, delay='10ms', max_queue_size=buffer_size)
net.build()
net.start()
time.sleep(1)
server_p=h2.popen("iperf3 -s")
#https://stackoverflow.com/questions/25702196/how-to-save-iperf-result-in-an-output-file
client_p=h1.popen("iperf3 -c 10.0.0.2 -i 1 -t 200 >client_output.txt", shell=True)
possion_p=h1.popen("./possion_sender 10.0.0.2 1234")
while True:
ret=subprocess.Popen.poll(client_p)
if ret is None:
continue
else:
break
os.killpg(os.getpgid(server_p.pid),signal.SIGTERM)
os.killpg(os.getpgid(possion_p.pid),signal.SIGTERM)
server_p.wait();
possion_p.wait()
net.stop()
print("done")
Extract the bandwidth values in client_output.txt and copy them to raw_rate.txt.
Processing the raw_rate.txt.
data_process.py
import os
if __name__ == '__main__':
capacity=10
rate_table=[2,4,6];
rawName="raw_rate.txt"
outName="bandwidth.txt"
f_out=open(outName,'w')
tick=0
duration=10
offset=0
for index, line in enumerate(open(rawName,'r')):
lineArr = line.strip().split()
if tick!=0 and tick%duration==0:
offset=(offset+1)%len(rate_table)
remain=int(capacity)-int(rate_table[offset])
f_out.write(str(tick)+"\t"+lineArr[0]+"\t"+str(remain)+"\n")
tick=tick+1;
The script to plot the results.
bw_plot.sh
#! /bin/sh
file=bandwidth.txt
output=bbr
gnuplot<<!
set xlabel "time/s"
set ylabel "rate/Mbps"
set xrange [0:200]
set yrange [0:10]
set term "png"
set output "${output}-bw.png"
plot "${file}" u 1:2 title "tcp rate" with lines lw 2,\
"${file4}" u 1:3 title "available bandwidth" with steps lw 2
set output
exit
!

Reference:
[1] change link bandwidth dynamically in mininet
边栏推荐
猜你喜欢

2. Log out, log in state examination, verification code

Introduction to C language function parameter passing mode

4. Publish Posts, Comment on Posts

3.用户上传头像

unity-shader(入门)
![[System Design and Implementation] Flink-based distracted driving prediction and data analysis system](/img/f0/23ac631b6eb9b794224d8ae78e6523.png)
[System Design and Implementation] Flink-based distracted driving prediction and data analysis system

px和em和rem的区别

STM32LL library use - SPI communication

光波导的入射耦合和出射耦合区域

Detailed introduction to the hierarchical method of binary tree creation
随机推荐
饥荒联机版Mod开发——准备工具(一)
LeetCode 2353. 设计食物评分系统 维护哈希表+set
锥形相位掩模的Talbot图像
5款最好用的免费3D建模软件(附下载链接)
2021-06-06
软件测试基础知识(背)
第三十三章:图的基本概念与性质
LeetCode 2354. 优质数对的数目 二进制01表示和集合之间的转换
关于混淆的问题
第三十二章:二叉树的存储与遍历
3. User upload avatar
仿真结果的格式&定制
剑指offer:数值的整数次方
VirtualLab Fusion中的可视化设置
光波导的入射耦合和出射耦合区域
戴森球计划这个游戏牛逼
golang内存相关文章-收集
Detailed explanation of MATLAB drawing function plot
质数相关问题-小记
【无标题】