网络传输机制-支持 TCP 可靠数据传输
实验内容
支持 TCP 可靠数据传输
- 网络丢包
- 超时重传机制
- 有丢包场景下的连接建立和断开
- 发送队列和接收队列
- 超时定时器实现
实验步骤
修改 tcp_apps.c(以及 tcp_stack.py),使之能够收发文件
执行 create_randfile.sh,生成待传输数据文件 client-input.dat
运行给定网络拓扑(tcp_topo.py)
在节点 h1 上执行 TCP 程序
- 执行脚本(disable_tcp_rst.sh, disable_offloading.sh),禁止协议栈的相应功能
- 在 h1 上运行 TCP 协议栈的服务器模式 (./tcp_stack server 10001)
在节点 h2 上执行 TCP 程序
执行脚本(disable_tcp_rst.sh, disable_offloading.sh),禁止协议栈的相应功能
在 h2 上运行 TCP 协议栈的客户端模式 (./tcp_stack client 10.0.0.1 10001)
- Client 发送文件 client-input.dat 给 server,server 将收到的数据存储到文件 server-output.dat
使用 md5sum 比较两个文件是否完全相同
使用 tcp_stack.py 替换其中任意一端,对端都能正确收发数据
设计思路
每个连接维护一个超时重传定时器
定时器管理
- 当发送一个带数据/SYN/FIN 的包,如果定时器是关闭的,则开启并设置时间为 200ms
- 当 ACK 确认了部分数据,重启定时器,设置时间为 200ms
- 当 ACK 确认了所有数据/SYN/FIN,关闭定时器
触发定时器后
- 重传第一个没有被对方连续确认的数据/SYN/FIN
- 定时器时间翻倍,记录该数据包的重传次数
- 当一个数据包重传 3 次,对方都没有确认,关闭该连接(RST)
超时重传实现
- 在 tcp_sock 中维护定时器
struct tcp_timer retrans_timer
。 - 当开启定时器时,将 retrans_timer 放到 timer_list 中。
- 关闭定时器时,将 retrans_timer 从 timer_list 中移除。
- 定时器扫描,每 10ms 扫描一次定时器队列,重传定时器的值为 200ms * 2^N。
tcp_set_retrans_timer
、tcp_update_retrans_timer
、tcp_unset_retrans_timer 函数
分别负责定时器的设置、更新以及删除。
tcp_scan_retrans_timer_list
函数
该函数负责扫描符合条件的定时器,若超时,则判断是否需要重传。
结果验证
由于实现简单重传机制非常耗时,此实验将传输文本大小缩短到了 500KB,另外为了验证本设计的鲁棒性,丢包率增大到了 10%。
本次实验的结果如下:
上图可知,可知本次实验结果符合预期,客户端发送的文件与服务器端接受的文件一致。