TCP 针对面试学习
文章目录
【注意】最后更新于 April 1, 2020,文中内容可能已过时,请谨慎使用。
什么是 TCP
- TCP 是一个全双工面向字节流的基于 IP 协议的协议。
- TCP 端到端的准确传输。
- 对于每一个字节进行确认
- 对于恶劣的网络情况的处理
- 超时重传
- 拥塞控制
- 效率提升
- 采用滑动窗口协议
- TCP 是一个面向连接的协议。
既然面向连接那这个连接是怎么建立的?
也就是下面的问题如果建立一个虚拟的链路采用三次握手。
三次挥手是怎么发生的
详细操作
从码出高效扒了一张图下来,我们来讲一下三次握手的流程:
- A 机器首先会计算出一个 seq 索引 x 表示当前发送的数据包的位置并且包的标示为 SYN。
- B 机器接受到了这个包,并且将包中的数据存到自己的缓冲区中,因为这个包的大小为 1 字节,所以缓存区的索引是 x + 1 同步到对方的发送 seq 位置,返回一个 SYN 和 ACK 标示的包,并且将自己的发送 seq 索引 y 以及告诉对方自己收到了这个数据包所以 ack + 1。
- C 机器收到这个带有 ACK 和 SYN 的包需要返回一个 ACK 表示自己能够收到对方的包,所以发送一个 ACK 和自己当前的发送 seq 以及自己的接受 seq。
为啥要握三次
至于为啥要握三次
主要有两点:
确保数据的对等性
-
首先需要确保双方的 seq 是彼此的接受与发送的缓冲区索引
-
确保彼此的接受和发送能力
第三次握手能保证 B 机器的发报能力,以及 A 机器的接受能力
防止脏连接
A 机器发送一个 SYN 包给 B 机器但是这个包被因为网络原因没有及时发到,又由于 TCP 的超时时间小于 TTL 因为如果 TCP 的超时间太长,那么重发封包的效率会很慢。
所以 A 机器又会发送一个 TCP,并且建立了连接,此时这个包已经到了 B 机器。
B 机器重新建立了连接,返回一个 ACK 给 A 机器。
如果只有两次握手的话,在 B 机器的视角就是已经建立了连接,但是 A 收到 B 的 Ack 的时候由于不是 SYN_SEND 所以直接丢弃,B 也无法感知,也就 B 存在单方面的脏连接了。
三次握手的话,B 需要有一次 A 的 ACK 确保自己的发送能力,同时也避免了脏连接,A 不会发送 ACK 给 B 所以 B 的视角也不会存在连接。
四次挥手是如何发生的
详细操作
确保双方的数据都处理完成。
- A 发送剩余数据已经 FIN 给 B 处于 FIN_WAIT
- B 回复 ACK 给 A
- B 等待一个 CLOSE_WAIT 再发送剩余的数据给 A
- A 回复 ACK 表示数据收到并等待 TIME_WAIT
为啥要四次挥手
需要保证双方的数据都处理完毕,并且彼此都知道。
第三次挥手是因为 A 机器告诉 B 机器不能传输数据并且 B 机器 ACK 之后,B 机器需要等待应用程序做一个处理才能发送一个 FIN 告诉 A 机器自己不能传输数据了。
第四次挥手是告诉 B 机器自己已经接受到 B 机器无法发送请求的事实。
TCP keepalive vs Http keepalive
HTTP
Http 如果在 header 添加 keepalive = true 就会使多个 http 请求在一条 TCP 连接上,不会像之前一样一个请求握手挥手一次。
优点:
降低服务端负载,在高并发的服务器下,服务端负载会减小
降低每个 http 请求的时间,因为如果是 http 请求都会有 SSL 或者 TSL 的行为和三次握手四次挥手,所以会很慢,但是 reduce 到一个连接就不会这样了。
TCP
是 OS 来维护的,因为每个 TCP 连接都有各种各样的定时器,TCP 也有 keepalive 的定时器,当 TCP 的 keepalive 定时器到达 0 的时候,就会向对方发送一个 ACK 为开启的探测包,因为 TCP 是面向流的协议。另一方面,您将收到来自远程主机的答复。并且这两个数据包的数据为空。
优点:
判断对方是否是 dead peer
防止由于网络不活动而断开连接。
文章作者 xiantang
上次更新 2020-04-01