计网实验三 TCP拥塞控制编程实验

一、实验要求

1. 掌握TCP进行拥塞控制的四种算法:慢开始、拥塞避免、快重传、快恢复的工作原理;

2. 编程实现拥塞控制算法。

二、实验环境

操作系统为Windows的计算机,安装有C、C++、Java、Python等编程工具。

三、实验要求

(1) 阅读互联网标准RFC5681文档。

(2) 掌握RFC5681的四种拥塞控制方法工作原理。

(3) 编程实现四种拥塞控制方法。要求:

① 程序具备必要的输入提示、输出提示。

② 程序输入:初始门限值、传输轮次。

③ 根据用户输入的“发生超时”或“收到三次重复确认”时的传输轮次实施拥塞控制。

④ 程序输出:各传输轮次的拥塞窗口值。

⑤ 可查询单个传输轮次的拥塞窗口值。

⑥ 考虑到实际的TCP拥塞窗口以字节为单位。

 (4) 画图描述出拥塞窗口的变化曲线,可参考下图。(选做内容)

PS!本代码参考文章:http://t.csdnimg.cn/Dexca,是在其基础上稍作改进,基本实现了该作者提出的不足之处。

四、代码实现

import numpy as np
from matplotlib import pyplot as plt
import matplotlib.font_manager as fm

# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei']  # 设置默认字体为黑体
plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题

def input_int(prompt):
    while True:
        try:
            return int(input(prompt))
        except ValueError:
            print("输入无效,请输入一个整数。")

# 程序输入
cwin = input_int('请输入初始拥塞窗口大小(单位:字节):')  # 拥塞窗口
ssthresh = input_int('请输入初始阈值大小(单位:字节):')  # 初始阈值

# 输入超时发生的传输轮次
timeout_rounds = input("请输入超时发生时的传输轮次(多个轮次用逗号分隔,没有则输入-1):")
ifTimeoutRoundIndex = list(map(int, timeout_rounds.split(','))) if timeout_rounds else []

# 输入重传发生的传输轮次
retransmission_rounds = input("请输入重传发生时的传输轮次(多个轮次用逗号分隔,没有则输入-1):")
ifReTransmissionRoundIndex = list(map(int, retransmission_rounds.split(','))) if retransmission_rounds else []

roundCount = input_int("请输入传输轮次:")  # 传输轮次

# 算法
listXResult = []  # 后期绘图用的x坐标集
listYResult = []  # 后期绘图用的y坐标集

for roundIndex in range(roundCount):
    print(f"第 {roundIndex} 轮:拥塞窗口大小:{cwin} 字节")

    # 图:收集x, y坐标
    listXResult.append(roundIndex)
    listYResult.append(cwin)

    # 先判断,是否超时或重传
    if roundIndex in ifTimeoutRoundIndex:
        ssthresh = cwin // 2
        cwin = 1
        continue
    if roundIndex in ifReTransmissionRoundIndex:
        ssthresh = cwin // 2
        cwin = ssthresh

    # 慢启动
    if cwin < ssthresh:
        cwin *= 2
        if cwin > ssthresh:
            cwin = ssthresh

    # 拥塞避免
    elif cwin >= ssthresh:
        cwin += 1

# 查询单个传输轮次的拥塞窗口值
while True:
    query_round = input("请输入要查询的传输轮次(输入-1退出查询):")
    if query_round == '-1':
        break
    try:
        query_round = int(query_round)
        if 0 <= query_round < roundCount:
            print(f"第 {query_round} 轮:拥塞窗口大小:{listYResult[query_round]} 字节")
        else:
            print("输入的传输轮次超出范围,请重新输入。")
    except ValueError:
        print("输入无效,请输入一个整数。")

# 绘制拥塞窗口变化曲线
plt.xlabel("传输次数 roundIndex")
plt.ylabel("拥塞窗口 cwin(单位:字节)")
plt.plot(listXResult, listYResult, 'r')
plt.grid()  # 添加网格
plt.title('拥塞窗口变化曲线')
plt.show()

另外,还有可以改进的部分,添加输入格式检查,增强代码健壮性。

代码仅供参考。

五、效果图:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值