美文网首页
TCP 拥塞控制程序模拟

TCP 拥塞控制程序模拟

作者: AndyDennisRob | 来源:发表于2020-06-06 00:38 被阅读0次

笔者花了一中午的时间,把早上学的TCP拥塞控制的情况进行模拟,写下这篇文章。

1.先来看看代码:

如果pip没配置镜像可以参考之前笔者写的另一篇博客,使用 pqi 来配置.那篇博客地址:

pip镜像管理和npm镜像管理

import time
import random
import matplotlib.pyplot as plt

"""
功能说明: 这是一个模拟使用快恢复和不适用快恢复的程序(TCP拥塞控制)
"""


def time_over(time_list: list, time_limit: int):
    """
    :param time_list: 要判断的列表
    :param time_limit: 限定的长度
    :return: 是否传进来的序列到达一定长度
    """
    if len(time_list) >= time_limit:
        draw_picture(time_list)
        return True
    return False


def draw_picture(draw_list: list):
    """
    :param draw_list: 要绘画的列表值
    :return: None
    """
    t = [i for i in range(1, len(draw_list) + 1)]
    fig = plt.figure()
    fig.suptitle('tcp congestion control simulation')
    # 设置横轴标签
    plt.xlabel("t")
    # 设置纵轴标签
    plt.ylabel("cwnd")
    plt.plot(t, draw_list)
    plt.show()


def congestion(start_cwnd: int, ssthresh: int, fast_recover: bool,
               time_limit: int, each_sleep: float, con_range: tuple):
    """
    :param start_cwnd: 开始时的报文数
    :param ssthresh: 初始的ssthresh值
    :param fast_recover:是否快恢复,即发送方是否收到三个重复确认
    :param time_limit: 模拟的时间控制(建议不小于20)
    :param each_sleep: 每个时间段模拟的时间.
    :param con_range: 网络拥塞窗口的范围,左闭右闭
    :return: cwnd_list,即拥塞窗口大小的列表
    """
    # 网络可能的拥塞窗口最小值
    con_min = con_range[0]
    # 网络可能的拥塞窗口最大值
    con_max = con_range[1]

    # 发生拥塞时的窗口大小
    congest_packet = random.randint(con_min, con_max)
    # 调试时用到 congest_packet = 15
    # 记录每一时刻的cwnd大小
    cwnd_list = [start_cwnd]
    cwnd = start_cwnd
    # 判断时间是否结束
    if time_over(cwnd_list, time_limit):
        return cwnd_list

    # 慢开始算法
    while cwnd * 2 < ssthresh:
        cwnd *= 2
        cwnd_list.append(cwnd)
        if time_over(cwnd_list, time_limit):
            return cwnd_list
        time.sleep(each_sleep)

    cwnd = ssthresh
    cwnd_list.append(cwnd)
    if time_over(cwnd_list, time_limit):
        return cwnd_list

    # 拥塞控制算法
    while cwnd < congest_packet:
        cwnd += 1
        cwnd_list.append(cwnd)
        if time_over(cwnd_list, time_limit):
            return cwnd_list
        time.sleep(each_sleep)

    # 此时网络拥塞了

    # 判断是否进行快恢复
    if fast_recover:
        time.sleep(each_sleep)

        # 以此类推
        while True:
            # 新的ssthresh值为发送窗口的一半
            ssthresh = congest_packet // 2
            cwnd = ssthresh
            cwnd_list.append(cwnd)
            if time_over(cwnd_list, time_limit):
                return cwnd_list

            # 新的发生拥塞时的窗口大小
            congest_packet = random.randint(con_min, con_max)
            # 调试时用到 congest_packet = 15

            # 拥塞控制算法
            while cwnd < congest_packet:
                cwnd += 1
                cwnd_list.append(cwnd)
                if time_over(cwnd_list, time_limit):
                    return cwnd_list
                time.sleep(each_sleep)

    else:
        time.sleep(each_sleep)
        # 不进行快恢复
        while True:
            # 新的ssthresh值为发送窗口的一半
            ssthresh = congest_packet // 2

            cwnd = start_cwnd
            cwnd_list.append(cwnd)
            time.sleep(each_sleep)

            # 慢开始算法
            while cwnd * 2 < ssthresh:
                cwnd *= 2
                cwnd_list.append(cwnd)
                if time_over(cwnd_list, time_limit):
                    return cwnd_list
                time.sleep(each_sleep)

            cwnd = ssthresh
            cwnd_list.append(cwnd)
            if time_over(cwnd_list, time_limit):
                return cwnd_list

            # 新的发生拥塞时的窗口大小
            congest_packet = random.randint(con_min, con_max)
            # 调试时用到 congest_packet = 15

            # 拥塞控制算法
            while cwnd < congest_packet:
                cwnd += 1
                cwnd_list.append(cwnd)
                if time_over(cwnd_list, time_limit):
                    return cwnd_list
                time.sleep(each_sleep)


if __name__ == '__main__':
    la = congestion(2, 12, True, 300, 0, (20, 100))
    lb = congestion(2, 12, False, 300, 0, (20, 100))
    print("la:\n", la)
    print("lb:\n", lb)

说明:由于网络情况是千变万化的,所以我这里用伪随机的方式生成拥塞时的窗口大小congest_packet.

然后这里模拟了300个单位时间内的情况.读者可以自行更改.

2.运行结果:

  • 会画出两幅图(由于拥塞窗口大小每次都是随机产生,所以每次执行会不太一样)

    这个是不采用快恢复的:


    不使用快恢复

采用快恢复的:


使用快恢复
  • 控制台:这是cwnd窗口的变化序列
    (其实右边还有,很长,这里截了一部分图)


    cwnd窗口变化序列

3.感想: 通过自己编程序模拟, 使得自己对TCP拥塞控制的机制更加熟悉。由于时间仓促,代码就还没进行优化,感兴趣的读者可以去优化一下. 感谢观看.

相关文章

  • TCP 拥塞控制程序模拟

    笔者花了一中午的时间,把早上学的TCP拥塞控制的情况进行模拟,写下这篇文章。 1.先来看看代码: 如果pip没配置...

  • 2018-07-11

    tcp的运输控制分为tcp流量控制和tcp拥塞控制,这里先讲tcp的拥塞控制。 为了讲清楚tcp的拥塞控制,还是利...

  • TCP Tahoe协议

    TCP Tahoe协议是TCP最早的TCP拥塞控制版本,主要包括三个机制用于控制拥塞窗口:慢启动、拥塞避免和快速重...

  • TCP拥塞控制算法之NewReno和SACK

    一、TCP Reno拥塞控制算法回顾 二、基于TCP Reno拥塞控制算法的改进 改进原因分析TCP Reno 提...

  • 细说TCP的可靠传输、流量控制、拥塞控制

    目录 TCP如何实现可靠传输? TCP如何实现流量控制?(滑动窗口) TCP如何实现拥塞控制?(慢开始、拥塞避免、...

  • 拥塞控制和流量控制

    滑动窗口的解释: 拥塞控制窗口+慢启动+拥塞控制算法=拥塞控制 TCP特性使得每个TCP连接可以得到均等的带宽。在...

  • TCP拥塞控制

    本文主要说明TCP拥塞控制的四种主要算法。 组成TCP拥塞控制的四种算法包括:慢开始,拥塞避免,快重传,快恢复, ...

  • 【转载】Google BBR是什么?以及在 CentOS 7 上

    TCP 拥塞控制算法 传统 TCP 拥塞控制算法,基于丢包反馈的协议。 基于「丢包反馈」的协议是一种被动式的拥塞控...

  • TCP的拥塞控制

    TCP使用了一个拥塞窗口和一个拥塞策略来避免拥塞,并在拥塞发生后检测和缓解拥塞。 1 拥塞窗口(congestio...

  • 拥塞控制算法对比

    RENO(经典的tcp拥塞控制): 基于丢包的拥塞控制. 分为 慢启动, 拥塞避免, 快速恢复, 快速重传...

网友评论

      本文标题:TCP 拥塞控制程序模拟

      本文链接:https://www.haomeiwen.com/subject/oyqttktx.html