概述
TCP连接:
用于保证可靠性和流量控制维护的某些状态信息,这些信息的组合,包括Socket、序列号和窗口大小称为连接。
建立一个 TCP 连接是需要客户端与服务器端达成三个信息的共识。
-
Socket:由 IP 地址和端口号组成
-
序列号:用来解决乱序问题等
-
窗口大小:用来做流量控制
如何唯一确定一个 TCP 连接呢?
四元组:
-
源地址
-
源端口
-
目的地址
-
目的端口
TCP和UDP区别
- TCP面向连接。UDP不需要连接
- TCP是一对一两点服务,UDP支持一对一,一对多,多对多。
- TCP可靠传输,UDP不可靠
三次握手
为什么是三次握手?不是两次、四次?
- 三次握手才可以阻止历史重复连接的初始化(主要原因)
可能会由于网络拥堵等乱七八糟的原因,会使得旧的数据包,先到达目标主机。
客户端连续发送多次 SYN 建立连接的报文,在网络拥堵等情况下:
一个「旧 SYN 报文」比「最新的 SYN 」 报文早到达了服务端;
那么此时服务端就会回一个 SYN + ACK 报文给客户端;
客户端收到后可以根据自身的上下文,判断这是一个历史连接(序列号过期或超时),那么客户端就会发送 RST 报文给服务端,表示中止这一次连接。
如果是两次握手连接,就不能判断当前连接是否是历史连接。
- 三次握手才可以同步双方的初始序列号
TCP 协议的通信双方, 都必须维护一个「序列号」, 序列号是可靠传输的一个关键因素,接收方可以去除重复的数据;可以根据数据包的序列号按序接收;这样一来一回,才能确保双方的初始序列号能被可靠的同步。
- 三次握手才可以避免资源浪费
如果客户端的 SYN 阻塞了,重复发送多次 SYN 报文,由于没有第三次握手,那么服务器在收到请求后就会建立多个冗余的无效链接,造成不必要的资源浪费。
四次挥手
MSL 是 Maximum Segment Lifetime,报文最大生存时间。
TIME_WAIT 等待 2 倍的 MSL,比较合理的解释是:网络中可能存在来自发送方的数据包,当这些发送方的数据包被接收方处理后又会向对方发送响应,所以一来一回需要等待 2 倍的时间。
比如,如果被动关闭方没有收到断开连接的最后的 ACK 报文,就会触发超时重发 Fin 报文,另一方接收到 FIN 后,会重发 ACK 给被动关闭方, 一来一去正好 2 个 MSL。
在 Linux 系统里 2MSL 默认是 60 秒,那么一个 MSL 也就是 30 秒。