三次握手过程
TCP三次握手我认为主要是保障连接的可靠性的,举个通俗点的例子来描述三次握手我觉得可以这么说,比如你妈打电话喊你吃饭
你妈:儿子,听得到我说话吗?(一次握手)
你:妈,听得到,你听得到我说话吗?(二次 握手)
你妈:听得到,饭煮好了快来吃饭(三次握手)
再来看详细过程
最开始时客户端和服务端都处于close状态,先是服务端主动监听某个端口,处于listen状态
1.客户端会随机初始化一个序列号(client_isn),seq= client_isn,同时将SYN标志为1(表示希望建立连接)接着将SYN报文发送给服务端,该报文不包含应用层数据,此时客户端处于SYN-SENT状态
2.服务端收到客户端的SYN报文后,也会随机生成一个序列号(server_isn)seq = server_isn,同时将确认应答号变为client_isn+1(ACK = client_isn+1),同时也把SYN和ACK标志位置置为1,最后将SYN-ACK报文发送给客户端,该报文也不包含应用层数据,此时服务端处于SYN-RCVD状态
3.客户端收到服务端报文后,还要向服务端回应最后一个应答报文,也是将该应答报文的ACK标注位置置为1,确认应答号变为server_isn+1(ACK = server_isn+1),最后将该报文发送给服务端,这次可以携带数据,之后客户端处于ESTABLISHED状态,服务端收到报文后也将处于ESTABLISHED状态
为什么需要三次握手
1.避免重复历史连接的初始化(主要原因)
三次握手最主要的原因是为了防止旧的重复连接初始化造成混乱
假如客户端发送了SYN(seq=90)报文,然后宕机了,而且这个报文还被网络阻塞了,服务端没有收到,接着客户端重启后,又重新向服务端建立连接,又重新发送了SYN(seq = 100)报文,此时旧的SYN报文就比最新的SYN报文先到达,服务端就会回一个SYN-ACK报文,而此报文确认号是90+1,客户端收到后发现不是100+1,就会回RST报文,服务端收到RST报文后就释放连接,后续新的报文又发送到后,就可以正常的三次握手了
而如果是两次握手的情况,服务端就没有中间状态给客户端来阻止历史连接,导致服务端可能建立一个历史连接,造成资源浪费。在两次握手的情况下,服务端在收到报文后就进入ESTABLISHED状态,建立连接,而客户端还未进入,假如此次连接是历史连接,像刚刚情况一样,服务端发送给客户端确认报文后,客户端发现不对,发送RST报文中止连接,服务器收到后将刚刚建立的连接关闭,可以发现这种情况无法避免历史连接问题
2.同步双方初始序列号
接收方可以去除重复的数据,接收方可以根据数据包的序列号按序接收,可以标识发送出去的数据包中, 哪些是已经被对方收到的(通过 ACK 报文中的序列号知道)