讲下TCP三次握手流程?
客户端和服务器初始均为CLOSED状态,然后服务器开始侦听某个端口进入LISTEN状态
(1)第一次握手:客户端发送SYN包(SYN=1,seq=x)到服务器,并进入SYN_SEND状态,等待服务器确认;
(2)第二次握手:服务器收到SYN包后并响应SYN+ACK包(SYN=1,ACK=1,seq=y.ack=x+1),发送完毕服务器进入SYN_RCVD状态;
(3)第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ACK=1,seq=x+1.ack=y+1)),此包发送完毕,客户端和服务器进入ESTABLISHED状态,后续开始交互数据。
为什么TCP是三次握手而不是两次、四次?
原因1:确认双方的接收与发送能力是否正常:
- 第一次握手(Client->Server,SYN):Server确认了自身接收正常,Client发送能力正常Client无法确认任何信息
- 第二次握手(Client<-Server,SYN+ACK):Server确认了自身接收正常,Client发送能力正常Client确认了自身收/发能力正常,Server收/发送能力正常
- 第三次握手(Client->Server,ACK):Server确认了自身收/发能力正常,Client收/发送能力正常Client确认了自身收/发能力正常,Server收/发送能力正常
所以三次握手能保证双方收发能力正常,二次握手不能确认,四次握手设计显得多余。
原因2:协商确定发送数据包的单位,即“最大消息长度”(MSS:Maximum Segment Size),如下:
举个例子:两个人互发微信交流如果一方直接发2000字长篇大论,另一方估计看都不想看,所以协商简洁的字数交流很有必要。
TCP交互也是一样,需要发送方和接收方协商能被双方认可的MSS才能有效交互,任何一方不能无限制的去乱发大包,这就会导致交互出现异常。
过程如下:
通过三次握手双方才能协商到最合适MSS以保证后续的数据交互标准,在TCP报文中MTU=MSS+40(20字节的TCP首部+20字节的IP首部)。
MSS协商存在于TCP Option字段中,协商报文如下: