1.IP层已经会分片,TCP层为什么还需要MSS呢?
先认识下MTU和MSS
如果TCP整个报文交给IP层分片,有什么后果?
当IP层有一个超过MTU大小的数据要发送,那么IP层就要进行分片,把数据分成若干片,保证每一个分片小于MTU,把一份IP数据报进行分片后,由目标主机的IP层进行重新组装,再交给上一层TCP传输层。 这看起来井然有序,但存在隐患,如果一个IP分片丢失,整个IP的报文都得重传 因为IP层本身没有超时重传机制,他由传输层的TCP负责超时和重传。 当接收方发现TCP报文的某一片丢失后,不会响应ACK给对方,那么发送方在TCP超时后,就会重发整个TCP报文(头部+数据) 因此,由IP层进行分片传输,是非常没有效率的。 所以,为了达到最大的传输效能TCP协议在建立连接的时候会协商双方的MSS值,当TCP层发现数据超过MSS时,会先进行分片,所以由形成的IP包也不会大于MTU,自然也不用进行IP分片了。 经过TCP层分片后,如果一个TCP分片丢失,重发也是以MSS为单位,不用重传所有的分片,大大增加了重传了效率。
2.第一次握手丢失会发生什么?
客户端与服务器建立TCP连接,首先第一个发的就是SYN报文,然后进入SYN_SEND状态,在这之后,如果客户端迟迟收不到服务端的SYN-ACK报文(第二次握手)就会触发超时重传机制,重传SYN报文。每次超时的时间是上一次的超时时间的2倍,大约经过一分钟左右,如果客户端迟迟收不到服务端回应的ACK,客户端不再发送SYN,然后断开TCP连接。
3.第二次握手丢失会发生什么?
当服务端收到客户端发送的第一次握手后,就会回SYN-ACK报文给客户端,这个就是第二次握手,此后服务端会进入SYN-RCVD状态。
第二次握手的SYN-ACK有两个目的
- 第二次握手的ACK,是对第一次握手的确认报文
- 第一次握手的SYN,是服务端发起建立TCP连接的报文
因为第二次握手报文包含着对客户端第一次握手的ACK确认报文,如果客户端迟迟没有收到第二次握手,客户端会觉得可能自已的SYN报文丢失了,于是客户端会触发超时重传机制,重传SYN报文。
然后,第二次握手包含着服务端的SYN报文,客户端收到后需要给服务端发送ACK确认报文(第三次握手),服务端才会认为该SYN报文被客户端接收到了
那么,如果第二次握手丢失了,服务端收不到第三次握手,会触发超时重传机制,重传SYN-ACK报文。
因此,第二次握手丢失了,客户端和服务端都会重传
- 客户端会重传SYN报文,也就是第一次握手,最大次数由tcp_syn_retries内核参数决定
- 服务端会重传SYN-ACK报文,也就是第二次握手,最大次数由tcp_synack_retries内核参数决定
4.第三次握手丢失了会发生什么?
客户端收到服务端给的SYN-ACK报文后,就会给服务端回一个ACK报文,也就是第三次握手,此后客户端进入ESTABLISH状态。
因为第三次握手的ACK是对第二次握手的SYN的确认报文,第三次握手丢失后,服务端迟迟收不到这个确认报文,就会触发超时重传机制,重传SYN-ACK报文,直到收到第三次握手,或者达到最大次数。
注意:ACK报文是不会重传,当ACK丢失后,只能由对方重传响应的报文。