参考资料:刘超老师的《趣谈网络协议》、王道考研《计算机网络》
TCP的特点
- 面向连接:三次握手、四次挥手
- 有序可靠:累次确认、丢失重传、超时重传
- 点到点:运输层解决不同主机进程通信问题,但实际上TCP连接的是进程的端口
- 窗口和RTT动态变化
- 全双工通信:TCP连接的每一端都有两个窗口:发送窗口与接收窗口
- 面向字节流
面向字节流
![image-20211029125406111](https://img-blog.csdnimg.cn/img_convert/47e1a014039159665555ad8aaa74cca1.png)
应用层将信息变成二进制流,再发给传输层。传输层再将二进制流变成数据报发送出去。
因为是面向字节流,因此TCP的传输机制是根据字节的序号进行的,而不是报文段。
TCP会根据对方的窗口大小以及信道拥塞程度,来决定发送多大字节的报文段。
TCP报文段
首部
- 端口
- 序号
- 确认号
- 数据偏移、保留、标识、窗口
- 校验、紧急
32bits * 5 = 20 字节,固定首部为20字节 。还有4字节是选项和填充字段,用来保持TCP首部长度。因此共24字节。
![image-20211029130232123](https://img-blog.csdnimg.cn/img_convert/32dad9464a2a16feeaa30499d28bce95.png)
![image-20211029130251459](https://img-blog.csdnimg.cn/img_convert/867cd7c2032a1009dfaab2c5e9105ddc.png)
序号字段
序号就是报文段的序号。报文被分隔成很多的报文段,每一段的报文段的序号就是该段第一个字节的序号。注意是以字节为单位。
![image-20211125070234460](https://img-blog.csdnimg.cn/img_convert/0ad8517bc2efc2b355bda51afcf674b2.png)
确认号字段
就是我想要从对方得到的报文段的序号,主要用于告诉对方下一次应该发什么给自己。
![image-20211125070244914](https://img-blog.csdnimg.cn/img_convert/0c17a7d980abcce6b4229f429087254c.png)
注意因为是用‘C’传递,所以Seq才会递增1的,具体的Seq号还得看数据的大小
状态标识字段
SYN 与 FIN
用于连接过程。SYN置为1表示请求建立连接,FIN置为1表示请求断开连接
数据缓存
![image-20211125070305042](https://img-blog.csdnimg.cn/img_convert/7bdf81c695c4967e71d92d21c851b444.png)
发送方缓存
接收方缓存
TCP的功能
连接过程
三次握手
- 客户发送一个SYN报文段,表示我想请求与你连接
- 服务器会从该数据报中提取出TCP SYN 报文段,为该TCP连接分配TCP缓存和变量,并向该客户TCP发送允许连接的报文段,表示我同意与你连接,这个报文段称作SYNACK报文段
- 客户接收到SYNACK报文段后,也会为TCP连接分配TCP缓存和变量,同时再发送一个报文段给服务器,告诉它我收到了你同意与我连接的信息了。
![](https://img-blog.csdnimg.cn/img_convert/f0c5e17513b2eae643f519a8bb0d9d38.png)
初始序号ISN
![image-20211029131913583](https://img-blog.csdnimg.cn/img_convert/4da3cf01e6f87e4467fdea23bf804908.png)
为什么不能两次握手
![image-20211029131951253](https://img-blog.csdnimg.cn/img_convert/988de5552d4566848b0799300da51ac3.png)
四次挥手
![image-20211125070355164](https://img-blog.csdnimg.cn/img_convert/baf06b0d2657366eaef57a63243d775d.png)
MSL
报文在网络中存在的最长时间,超过这个时间报文就要被抛弃。
为什么要等待2MSL?
- 保证最后一个ACK报文到达
- 防止“已失效的连接请求报文段”出现在本连接中
可靠传输
对于失序的报文段,没有明确的处理办法,具体看编程人员怎么处理。
累次确认
![image-20211125070416458](https://img-blog.csdnimg.cn/img_convert/e2f77e21671d196d372aa3e32017ddeb.png)
丢失重传
![image-20211125070421926](https://img-blog.csdnimg.cn/img_convert/aefc4b323403e75d629dd97195c99907.png)
超时重传
![image-20211029132333813](https://img-blog.csdnimg.cn/img_convert/a11ffb2641981fb2ac31bb9cea1bdf0e.png)
ACK发送时机
![image-20211029132415045](https://img-blog.csdnimg.cn/img_convert/4bc3421e4fdc38ec29b2acd0192c87ac.png)
快速重传
当连续接到3个重复的ACK(注意是不包括原数据的那个ACK),发送方马上重传。
![image-20211029132438973](https://img-blog.csdnimg.cn/img_convert/bde6dbb1d1e3db74e1079ab0f4322de6.png)
选择确认 SACK
在双方赞同的情况下,可以使用SR协议。
如果使用选择确认,那么原来首部中的“确认号字段”的用法仍然不变。只是以后在 TCP 报文段的首部中都增加了 SACK 选项,以便报告收到的不连续的字节块的边界。
往返时间的估计与超时
往返时间的估计
上一次估计值与本轮观测值的加权和
![image-20211029132650607](https://img-blog.csdnimg.cn/img_convert/f14dbde5ae0a9cf2f9191b10f65ecffe.png)
时间间隔设定多久为超时?
往返时间+安全边界值
![image-20211029132709372](https://img-blog.csdnimg.cn/img_convert/7cbfba0301ee975e0eb8a8dbaa910d06.png)
![img](https://img-blog.csdnimg.cn/img_convert/19a9278e7d94a965046bb9da1f2f16d4.png)
karn算法
![image-20211029132802347](https://img-blog.csdnimg.cn/img_convert/32bc4b79cc6b855743c4eadb904a90d9.png)
![image-20211029132806246](https://img-blog.csdnimg.cn/img_convert/e0205667b4ed0b578b4a33d0032a7212.png)
流量控制
通过接收方告诉发送方自己的窗口大小,让发送端设计合适的窗口大小来发送分组,保证速度匹配。
变量解释
- rwnd:接收窗口,接收方设置,并发送给发送方让其进行维护
- RcvBuffer:接收缓存,由接收方来维护
- LastByteRead:主机B上的应用进程从缓存读出的数据流的最后一个字节的编号,即缓存中第一个数据字节编号-1
- LastByteRcvd:从网络中到达的并且已放入主机B接收缓存中的数据流的最后一个字节的编号,即缓存中最后一个数据的字节编号
设置接收窗口
spare room in buffer
= RcvWindow
= RcvBuffer-[LastByteRcvd - LastByteRead]
![image-20211029133015729](https://img-blog.csdnimg.cn/img_convert/021b05e4aed7b80a5901aa12c03821a6.png)
![image-20211029133119116](https://img-blog.csdnimg.cn/img_convert/2b040d0503614cf662beb06001d3f196.png)
发送方维护一个接收窗口(变量),接收窗口用来告诉发送方接收方还有多少可用的缓存空间;当发送方知道接收方缓存空间用完时,即接收窗口为0,发送方就不发了。现在问题就来了,接收方会逐渐清理缓存,但发送方并不知道接收方什么时候清理,那样就会出现死锁状态
通过持续计时器打破死锁
发送方的接收窗口为0时,会启动持续计时器,计时器结束就会发送一个窗口探测报文段,接收方确认这个探测报文段时,就返回了它现在缓存空间的大小,如果还是0,那么重复执行这个操作,直到不为0时,发送方就可以发送报文段了.
优化
只靠持续计时器,效率太低了,因此又加了两种方式来提高效率:
- 第一种机制是 TCP 维持一个变量,它等于最大报文段长度 MSS。只要缓存中存放的数据达到 MSS 字节时,就组装成一个 TCP 报文段发送出去。
- 第二种机制是由发送方的应用进程指明要求发送报文段,即 TCP 支持的推送(push)操作
拥塞控制
当出现以下两种情况时,一般认为发送了拥塞:
拥塞窗口
拥塞窗口指发送端在一个RTT内可以最多发送的数据包数
![image-20211029134113621](https://img-blog.csdnimg.cn/img_convert/2468c153d72cf79aeec0af3f45a2655d.png)
发送窗口
![image-20211029134133659](https://img-blog.csdnimg.cn/img_convert/a0c9b02ed73aba03256d2e332cc89c31.png)
拥塞控制算法
慢开始算法
![image-20211029134353055](https://img-blog.csdnimg.cn/img_convert/8c6def7340752470aaacd5ad26f1f1d4.png)
![QQ截图20211125070637](https://img-blog.csdnimg.cn/img_convert/25b9735270abdf1e1b5a4ed21690b144.png)
拥塞避免算法
![image-20211029134401638](https://img-blog.csdnimg.cn/img_convert/e4a61dfe68297b28c477e88c7df9adb6.png)
慢开始与拥塞避免的搭配使用
![image-20211029134406649](https://img-blog.csdnimg.cn/img_convert/ac3364e084a8d057075bae2a8f6d031c.png)
![image-20211029134410303](https://img-blog.csdnimg.cn/img_convert/8bb135236919955e0b8b5238c44b4e15.png)
![image-20211029134413206](https://img-blog.csdnimg.cn/img_convert/ec46ae9f3a7a9992df5b1934db961645.png)
快重传算法
发送方:
- 只要一连收到三个重复确认就应当立即重传对方尚未收到的报文段
- 每收到一个失序的报文段后就立即发出重复确认。这样做可以让发送方及早知道有报文段没有到达接收方。
接收方:
- 每收到一个失序的报文段后就立即发出重复确认。这样做可以让发送方及早知道有报文段没有到达接收方。
快恢复算法
![image-20211029134248174](https://img-blog.csdnimg.cn/img_convert/8d249c6cad3a6c127a52e728fa3d8240.png)
快重传与快恢复算法的搭配使用
![image-20211029134243558](https://img-blog.csdnimg.cn/img_convert/b1b216619860298f7df80c5d83c4c307.png)
注意一点,计算机网络中,慢开始+拥塞避免是必须存在的,而快开始和快恢复是为了提高效率,有则更好。
BBR 拥塞算法
拥塞控制的两个不合理点:
- 拥塞判断不够合理,公网上带宽不满也会丢包,并不一定是拥塞。
- 填满才认为会发生丢包,太晚了。这样有可能会把缓存也填满。
![image-20211029135838179](https://img-blog.csdnimg.cn/img_convert/7302f1b7265ef4dceeb0040447869dbf.png)
TCP状态机
![image-20211028164306688](https://img-blog.csdnimg.cn/img_convert/01382e96aea58c19113cd42c0163e05f.png)
|