change the available bandwidth of tcp flow dynamically in mininet

  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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值