TCP数据的传输过程(十)
建立连接后,两台主机就可以相互传输数据了。如下图所示:
上图给出了主机A分2次(分2个数据包)向主机B传递200字节的过程。首先,主机A通过1个数据包发送100个字节的数据,数据包的 Seq 号设置为 1200。主机B为了确认这一点,向主机A发送 ACK 包,并将 Ack 号设置为 1301。
为了保证数据准确到达,目标机器在收到数据包(包括SYN包、FIN包、普通数据包等)包后必须立即回传ACK包,这样发送方才能确认数据传输成功。
此时 Ack 号为 1301 而不是 1201,原因在于 Ack 号的增量为传输的数据字节数。假设每次 Ack 号不加传输的字节数,这样虽然可以确认数据包的传输,但无法明确100字节全部正确传递还是丢失了一部分,比如只传递了80字节。因此按如下的公式确认 Ack 号:
Ack号 = Seq号 + 传递的字节数 + 1
与三次握手协议相同,最后加 1 是为了告诉对方要传递的 Seq 号。
下面分析传输过程中数据包丢失的情况,如下图所示:
上图表示通过 Seq 1301 数据包向主机B传递100字节的数据,但中间发生了错误,主机B未收到。经过一段时间后,主机A仍未收到对于 Seq 1301 的ACK确认,因此尝试重传数据。
为了完成数据包的重传,TCP套接字每次发送数据包时都会启动定时器,如果在一定时间内没有收到目标机器传回的 ACK 包,那么定时器超时,数据包会重传。
上图演示的是数据包丢失的情况,也会有 ACK 包丢失的情况,一样会重传。
1. 重传超时时间(RTO, Retransmission Time Out)
这个值太大了会导致不必要的等待,太小会导致不必要的重传,理论上最好是网络 RTT 时间,但又受制于网络距离与瞬态时延变化,所以实际上使用自适应的动态算法(例如 Jacobson 算法和 Karn 算法等)来确定超时时间。
往返时间(RTT,Round-Trip Time)表示从发送端发送数据开始,到发送端收到来自接收端的 ACK 确认包(接收端收到数据后便立即确认),总共经历的时延。
2. 重传次数
TCP数据包重传次数根据系统设置的不同而有所区别。有些系统,一个数据包只会被重传3次,如果重传3次后还未收到该数据包的 ACK 确认,就不再尝试重传。但有些要求很高的业务系统,会不断地重传丢失的数据包,以尽最大可能保证业务数据的正常交互。
最后需要说明的是,发送端只有在收到对方的 ACK 确认包后,才会清空输出缓冲区中的数据。
最新文章
- 【leetcode】Search for a Range
- php使用正则过滤js脚本代码实例
- 在多台服务器上简单实现Redis的数据主从复制(3)(转载)
- .naturalWidth 和naturalHeight属性,
- POJ #1015 - Jury Compromise - TODO: POJ website issue
- php的session实现
- 前端面试题第二波,要offer的看过来~
- UVA10534-----Wavio Sequence-----动态规划之LIS
- .net core 2.0 redis驱动性能比拼
- 删除N天前的文件(夹)与拷贝文件到共享盘的批处理
- select实现高并发服务器
- React Fiber源码分析 第三篇(异步状态)
- linqjs
- oracle逐步学习总结之权限和角色(基础六)
- 团队作业——Alpha冲刺 10/12
- IDEA中 @override报错的解决方法
- centos 6.8 解决ibus输入法不正常显示的问题
- BZOJ1856: [Scoi2010]字符串(组合数)
- getTextContent()方法会出现The method getTextContent() is undefined for the type Node 提示
- 持续集成:TeamCity 的安装和使用
热门文章
- LG4824 「USACO2015FEB」(Silver)Censoring KMP+栈
- eclipse git pull 代码 failed 并且报DIRTY_WORKTREE.classpath
- C# Windows服务创建安装卸载
- Java调试平台体系JPDA
- CF-378 B.Semifinals
- FFmpeg 常用结构体
- FaaS(函数即服务) + BaaS(后台即服务)
- vuex 源码解析(四) mutation 详解
- 离线缓存 Visual Studio 2019 (VS2019)的方法
- 发布.net core项目 System.AggregateException: 发生一个或多个错误