tcp看书总结
17章 传输控制协议
- 面向连接的、可靠的字节流服务。
- tcp报文长度,20字节IP首部+20字节TCP首部
- 20字节TCP首部 = 两个端口号4字节+seq4字节+ack4字节+标志位和窗口等4字节+校验和紧急指针4字节
- MSS(Maximum Segment Size)最长报文大小, SYN时指定,代表本端所能接收的最大长度报文段。
- tcp请求包里如果没有包的data数据,一般就占用40字节。
18章 TCP连接的建立与终止
- MTU(Max Tran Unit) 最大传输单元,=MSS+40字节
- 三次握手,建立连接,同步双方的序列号 + 滑动窗口值 + 最大报文长度。
- 四次挥手,双方向的关闭连接。
- 状态图变化,这个要找点例题学习一下。
- TCP维护一个固定长度的连接队列,该队列中的连接已被TCP接受,但还没有被应用层所接受。
- 一个TCP连接由一个4元组唯一确定:本地IP+本地端口+远端IP+远端端口。
19章 TCP的交互数据流
- 延时ACK。 通常TCP在接收到数据时并不立即发送ACK,相反推迟发送,以便将ACK与需要沿该方向发送的数据一起发送。
- Nagle算法。
- 目的:小分组会增加拥塞出现的可能性。
- 逻辑:要求一个TCP连接上最多只能有一个未被确认的未完成的小分组,在该分组的确认到达之前不能发送其它的小分组。
20章 TCP的成块数据流
- 滑动窗口协议。接收方的流量控制方法。允许发送方在停止并等待确认前可以连续发送多个分组。 可以加速数据的传输。
- PUSH标志。 发送方使用该标志,通知接收方将收到的数据全部提交给接收进程。
- 慢启动算法。 发送方的流量控制方法。
- 目的:发送方和接收方之前存在比较慢的链路时,减少链路拥塞的可能性。
- 逻辑:新分组进入网络的速率应该与另一端返回确认的速率相同。
- 逻辑实现:
- 发送方的TCP增加一个窗口,拥塞窗口(congestion window, 记为cwnd)。
- 收到一个ACK, 拥塞窗口就加1.
- 拥塞窗口预期指数增长,直到滑动窗口上限。
- RTT(Round Trip Time) 往返时间。
21章 TCP的超时与重传
- 拥塞避免算法。
- 处理丢失分组的方法。 中间路由器达到极限,导致分组被丢弃。 此时用拥塞避免算法来处理这种场景。
- 逻辑:发生分组丢失时,我们希望降低分组进入网络的传输速率。拥塞避免和慢启动算法的目的一样,在实际中两个算法通常在一起实现。
- 实现逻辑:
- cwnd处理拥塞窗口, 用于慢启动。
- ssthresh 慢启动门限(自己理解就是一个阈值)
- 发生拥塞时, ssthresh设置为X窗口的一半。(X窗口=cwnd和滑动窗口的最小值)
- 如果命中了ssthresh限制,cwnd的增长将不再是指数增长(不再使用慢启动算法),相反使用线性增长。 达到减少分组进入网络的目的。
- 快速重传
- 场景:发送方感知到发送报文段丢失的时候,直接重传丢失的报文段,无需等待超时定时器溢出。
- 逻辑:需要区分报文段是“丢失”还是“乱序”到达,区分逻辑是收到N(N=3)个重复ACK时, 则为丢失。 小于N时, 则为乱序。当然,如果没有收到ACK, 那就是网络问题了。
- 实现逻辑:收到3个重复ACK时,直接快速重传丢失的分组。
- 快速恢复
- 分组丢失之后,进行快速重传 + 拥塞避免。 这个就是快速恢复算法。 个人理解是这样子的。
- 要看看快速恢复算法和拥塞避免算法的区别。
- TCP超时重传时,允许重新分组。重组发送一个较大的报文段,有助于提高性能。
22章 TCP的坚持定时器
- 在连接的一方需要发送数据但对方已通告窗口大小为0时,就需要设置TCP的坚持定时器。这个探查过程将一直持续下去。
- 坚持定时器使用了普通的TCP指数退避。 最长60秒发送一次。
- 窗口探查包含一个字节的数据,由于接收方滑动窗口为0, 因此ACK并不是确认该字节,这个字节将被持续重传。
- 糊涂窗口综合症(silly window syndrome)
- 书上都没说什么是“糊涂窗口综合症”,只能自己找找资料了。
- 糊涂窗口综合症是指当发送端应用进程产生数据很慢、或接收端应用进程处理接收缓冲区数据很慢,或二者兼而有之;就会使应用进程间传送的报文段很小,特别是有效载荷很小; 极端情况下,有效载荷可能只有1个字节;传输开销有40字节(20字节的IP头+20字节的TCP头) 这种现象。
- 简而言之,就是接收方消耗缓冲区数据太慢,导致小包频繁出现。
- 解决方法:
- 发送方:nagle算法,连接中只允许存在一个未被确认的小分组。
- 接收方:
- Clark算法。 直接回复ACK, 但是窗口值设置为0. 需要发送方用坚持定时器来探查。
- 延迟确认。 优点是减少了通信量。
23章 TCP的保活定时器
- 工程中的保活,一般依赖应用程序来完成。 个人觉得这个功能用处不大。略过。
其它资料补充:
皓叔这两篇文章很棒, 也引用一下。
TCP那些事 上下篇
https://coolshell.cn/articles/11564.html
https://coolshell.cn/articles/11609.html
下篇里下面这一段说得特别棒,摘抄一下。
上面我们知道了,TCP通过Sliding Window来做流控(Flow Control),但是TCP觉得这还不够,因为Sliding Window需要依赖于连接的发送端和接收端,其并不知道网络中间发生了什么。TCP的设计者觉得,一个伟大而牛逼的协议仅仅做到流控并不够,因为流控只是网络模型4层以上的事,TCP的还应该更聪明地知道整个网络上的事。
具体一点,我们知道TCP通过一个timer采样了RTT并计算RTO,但是,如果网络上的延时突然增加,那么,TCP对这个事做出的应对只有重传数据,但是,重传会导致网络的负担更重,于是会导致更大的延迟以及更多的丢包,于是,这个情况就会进入恶性循环被不断地放大。试想一下,如果一个网络内有成千上万的TCP连接都这么行事,那么马上就会形成“网络风暴”,TCP这个协议就会拖垮整个网络。这是一个灾难。
所以,TCP不能忽略网络上发生的事情,而无脑地一个劲地重发数据,对网络造成更大的伤害。对此TCP的设计理念是:TCP不是一个自私的协议,当拥塞发生的时候,要做自我牺牲。就像交通阻塞一样,每个车都应该把路让出来,而不要再去抢路了。
关于拥塞控制的论文请参看《Congestion Avoidance and Control》(PDF)
拥塞控制主要是四个算法:1)慢启动,2)拥塞避免,3)拥塞发生,4)快速恢复。这四个算法不是一天都搞出来的,这个四算法的发展经历了很多时间,到今天都还在优化中。 备注:
1988年,TCP-Tahoe 提出了1)慢启动,2)拥塞避免,3)拥塞发生时的快速重传
1990年,TCP Reno 在Tahoe的基础上增加了4)快速恢复