TCP1
TCP1
引用:小林coding
1. 什么是TCP
TCP 是面向连接的、可靠的、基于字节流的传输层通信协议。
2. TCP与UDP区别
TCP | UDP | |
---|---|---|
连接 | TCP 是面向连接的传输层协议,传输数据前先要建立连接。 | UDP 是不需要连接,即刻传输数据。 |
服务对象 | TCP 是一对一的两点服务,即一条连接只有两个端点。 | UDP 支持一对一、一对多、多对多的交互通信 |
可靠性 | TCP 是可靠交付数据的,数据可以无差错、不丢失、不重复、按序到达。 | UDP 是尽最大努力交付,不保证可靠交付数据。 |
拥塞控制、流量控制 | TCP 有拥塞控制和流量控制机制,保证数据传输的安全性。 | UDP 则没有,即使网络非常拥堵了,也不会影响 UDP 的发送速率。 |
首部开销 | TCP 首部长度较长,会有一定的开销。 | UDP 首部只有 8 个字节,并且是固定不变的,开销较小。 |
传输方式 | TCP 是流式传输,没有边界,但保证顺序和可靠。 | UDP 是一个包一个包的发送,是有边界的,但可能会丢包和乱序。 |
分片不同 | TCP 的数据大小如果大于 MSS 大小,则会在传输层进行分片 | UDP 的数据大小如果大于 MTU 大小,则会在 IP 层进行分片 |
3. TCP三次握手
3.1 三次握手建立过程
其中第三次握手是可以携带数据的
3.2 为什么是三次握手,而不是两次、四次?
三次握手可以阻止重复的历史连接(最重要)
由于网络超时导致客户端报文超时重发,序列号机制可以确保之前阻塞在网络中的报文不会起作用
三次握手才可以同步双方的初始序列号
客户端
SYN
报文告诉对方自己的初始序列号client_isn
,服务端ACK
这个报文client_isn + 1
,SYN
报文告诉对方自己的初始序列号server_isn
,客户端ACK
这个报文server_isn + 1
序列号是TCP可靠传输的一个重要机制:
- 接收方可以去除重复的数据;
- 接收方可以根据数据包的序列号按序接收;
- 可以标识发送出去的数据包中, 哪些是已经被对方收到的(通过
ACK
报文中的序列号知道);
三次握手可以避免资源浪费
若只有两次握手,那么服务端回复
ACK
+SYN
报文后,不知道对方能不能接收到,于是都会建立连接,如果客户端因为网络阻塞发送了多个SYN
报文,服务端这边就会建立多个连接,造成资源浪费
故不用「两次握手」与「四次握手」的原因:
- 「两次握手」:无法防止历史连接的建立,会造成双方资源的浪费,也无法可靠的同步双方序列号;
- 「四次握手」:三次握手就已经理论上最少可靠连接建立,所以不需要使用更多的通信次数。
3.3 为什么每次建立TCP连接时,初始序列号都不相同
若每次初始序列号都从0开始,很容易出现历史报文被下一个相同四元组的连接接收的问题
3.4 三次握手丢失分别会发生什么?
- 第一次握手丢失:客户端由于没收到回应,超时重传
SYN
报文 - 第二次握手丢失:客户端由于没收到回应,超时重传
SYN
报文;服务端由于没收到回应,超时重传ACK
+SYN
报文 - 第三次握手丢失:
ACK
报文是不会有重传的,当ACK
丢失了,就由对方重传对应的报文,即服务端超时重传ACK
+SYN
报文
4. TCP四次挥手
4.1 四次挥手建立过程
- 关闭连接时,客户端向服务端发送
FIN
时,仅仅表示客户端不再发送数据了但是还能接收数据。 - 服务端收到客户端的
FIN
报文时,先回一个ACK
应答报文,服务端可能还有数据需要处理和发送,等服务端不再发送数据时,才发送FIN
报文给客户端来表示同意现在关闭连接。
从上面过程可知,服务端通常需要等待完成数据的发送和处理,所以服务端的 ACK
和 FIN
一般都会分开发送,因此是需要四次挥手。
4.2 四次挥手分别丢失会发生什么?
- 第一次挥手丢失:客户端超时重发
FIN
报文 - 第二次挥手丢失:由于
ACK
报文是不会重发的,故客户端超时重发FIN
报文 - 第三次挥手丢失:服务端超时重传
FIN
报文 - 第四次挥手丢失:服务端超时重传
FIN
报文
4.3 为什么TIME_WAIT等待的时间是2MSL?
MSL
是 Maximum Segment Lifetime,报文最大生存时间,它是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。
当客户端第四次挥手ACK
报文没有传到服务端,服务端会超时重传第三次挥手的FIN
报文,TIME_WAIT
设置成2MSL
可以保证客户端能够收到这个重传的FIN
报文,收到重传报文后刷新TIME_WAIT
时间并重发ACK
TIME_WAIT
的作用:
为了防止历史连接中的数据,被后面相同四元组的连接错误的接收,因此 TCP 设计了 TIME_WAIT 状态,状态会持续
2MSL
时长,这个时间足以让两个方向上的数据包都被丢弃,使得原来连接的数据包在网络中都自然消失,再出现的数据包一定都是新建立连接所产生的等待足够的时间以确保最后的 ACK 能让被动关闭方接收,从而帮助其正常关闭