关于TCP握手和挥手告别
tcp协议格式
clipboard.png三次握手
在 TCP/IP 协议中,TCP 协议提供可靠的连接服务,采用三次握手建立一个连接。
clipboard.png
第一次握手:建立连接时,客户端发送 syn 包(tcp协议中syn位置1,序号为J)到服务器,并进入 SYN_SEND 状态,等待服务器确认;
第二次握手:服务器收到 syn 包,必须确认客户的 SYN,同时自己也发送一个 SYN 包,即 SYN+ACK包(tcp协议中syn位置1,ack位置1,序号K,确定序号为J+1),此时服务器进入 SYN_RECV 状态;
第三次握手:客户端收到服务器的 SYN+ACK 包,向服务器发送确认包 ACK(tcp协议中ack位置1,确认序号K+1),此包发送完毕,客户端和服务器进入 ESTABLISHED 状态,完成三次握手。
clipboard.png
通过这样的三次握手,客户端与服务端建立起可靠的双工的连接,开始传送数据。 三次握手的最主要目的是保证连接是双工的,可靠更多的是通过重传机制来保证的。
挥手告别
clipboard.png1)客户端 A 在应用层调用close时会激发底层发送一个 FIN(tcp协议中FIN位置1、序号为M,结合上图分析)请求,用来关闭客户 A 到服务器 B 的数据传送,客户端A此时处于半关闭状态(应用层无法接收数据但底层还可以接收数据);
2)服务器 B 底层收到客户端A的FIN时会做两件事
2.1)第1件事:收到客户端A的FIN时底层会主动回发一个ACK(tcp协议中ACK位置1,确认序号M+1)
2.2)第2件事:收到客户端A的FIN时,导致服务器B的应用层read()返回0(告诉服务器B应用层:客户端A关闭了)
3)服务器B应用层调用close()激发底层给客户端 A 发送一个 FIN(tcp协议中FIN位置1、序号为N),这是服务器B已处于半关闭状态;
4)客户端 A 底层回发 ACK(tcp协议中ACK位置1,确认序号N+1) 给服务器B,这是客户端A、服务器B都处于完全关闭状态,回收相应的资源。
这是因为服务端的 LISTEN 状态下的 SOCKET 当收到 SYN 报文的建连请求后,它可以把 ACK 和 SYN(ACK 起应答作用,而 SYN 起同步作用)放在一个报文里来发送。但关闭连接时,当收到FIN 报文通知时,如果能将ACK、FIN放在一个报文里那么就有了三次挥手,但是这是不可能,因为ACK是服务器B一收到FIN报文底层就回发的,而服务器B的FIN是应用层调用close()激发的,所以它这里的 ACK 报文和 FIN 报文在发送的时间上都是分开的,不可能同时发送。
网友评论