1.1、 面向连接(三次握手)
面向连接(三次握手):在通信之前,会先通过三次握手的机制来确认两端口之间的连接是否可用。
三次握手机制:
一开始客户端和服务端都是关闭状态,但是在某个时刻,客户端需要和服务端进行通信,此时双方都会各自准备好端口,服务器段的端口会处于监听状态,等待客户端的连接。
客户端可会知道自己的端口号,和目的进程的端口号,这样才能发起请求。
第一次握手:客户端想与服务器进行连接了,所以状态变为主动打开,同时发送一个连接请求报文给服务器段SYN=1,并且会携带x个字节过去。
发送完请求连接报文后,客户端的状态就变为了SYN_SENT,可以说这个状态是等待发送确认(为了发送第三次握手时的确认包)
第二次握手:服务端接收到连接请求报文后,从LSTTEN状态变为被动打开状态,然后给客户端返回一个报文。这个报文有两层意思,一是确认报文,而可以达到告诉客户端,我也打开连接了。
发完后,变为SYN_RCVD状态(也可以说是等待接受确认状态,接受客户端发过来的确认包)
第三次握手:客户端得到服务器端的确认和知道服务器端也已经准备好了连接后,还会发一个确认报文到服务器端,告诉服务器端,我接到了你发送的报文,接下来就让我们两个进行连接了。
客户端发送完确认报文后,进入ESTABLISHED,而服务器接到了,也变为ESTABLISHED。
1.2、同时打开连接请求
正常情况下,通信一方请求建立连接,另一方响应该请求,但是如果出现,通信双方同时请求建立连接时,则连接建立过程并不是三次握手过程,而且这种情况的连接也只有一条,并不会建立两条连接。
同时打开连接时,两边几乎同时发送 SYN,并进入 SYN_SENT 状态,当每一端收到 SYN 时,状态变为 SYN_RCVD,同时双方都再发 SYN 和 ACK 作为对收到的 SYN 进行确认应答。
当双方都收到 SYN 及相应的 ACK 时,状态变为 ESTABLISHED
1.3、三次握手的原因(仅限参考)
最终原因:防止服务器资源浪费
由于网络原因(1)消息被阻塞在了某个节点,然后阻塞的时间超出设定的时间,会认为这个消息丢失了,然后重新发送消息。
(2)包丢失
情景模拟:
1、客户端对服务器说:“服务器我有要创建一个连接A,我们进行第一次握手”,等待服务器的回答
2、服务器面临的情况有三种
(1)包丢失,不反应------不浪费资源
(2)包正常到达,回答客户端:“你的第一次握手我收到了,你可以建立连接A了”
(3)由于网络阻塞,客户端发送俩次,服务器收到俩次,回答俩次
3、客户端面临的情况
(1)正常收到服务器回复,并发送三次握手“我已建立连接状态,服务器你也来啊”
(2)收到服务器发送的多条回复,将由于阻塞的回复过滤,并发送三次握手“我已建立连接状态,服务器你也来啊”
4、服务器情况
(1)收到客户端的第三次握手,建立连接
(2)包丢失,没有收到,客户端资源浪费,服务端资源没有浪费
2.1、TCP释放连接(四次挥手)
通信完成后,连接就会被释放,通过四次挥手机制来完成这个事情。
第一次挥手:从ESTABLISHED变为主动关闭状态,客户端主动发送释放连接请求给服务器端,FIN=1。发送完之后就变为FIN_WAIT_1状态,这个状态可以说是等待确认状态。
第二次挥手:服务器接收到客户端发来的释放连接请求后,状态变为CLOSE_WAIT,然后发送确认报文给客户端,告诉他我接收到了你的请求。为什么变为CLOSE_WAIT,原因是是客户端发送的释放连接请求,
可能自己这端还有数据没有发送完呢,所以这个时候整个TCP连接的状态就变为了半关闭状态。服务器端还能发送数据,并且客户端也能接收数据,但是客户端不能在发送数据了,只能够发送确认报文。
客户端接到服务器的确认报文后,就进入了FIN_WAIT_2状态。也可以说这是等待服务器释放连接状态。
第三次挥手:服务器端所有的数据度发送完了,认为可以关闭连接了,状态变为被动关闭,所以向客户端发送释放连接报文,发完之后自己变为LAST_WAIT状态,也就是等待客户端确认状态
第四次挥手:客户端接到释放连接报文后,发送一个确认报文,然后自己变为TIME_WAIT,而不是立马关闭,因为客户端发送的确认报文可能会丢失,丢失的话服务器就会重传一个FIN,也就是释放连接报文,
这个时候客户端必须还没关闭。 当服务器接受到确认报文后,服务器就进入CLOSE状态,也就是关闭了。但是由于上面说的这个原因,客户端必须等待一定的时间才能够进入CLOSE状态。
2.2、同时关闭连接
正常情况下,通信一方请求连接关闭,另一方响应连接关闭请求,并且被动关闭连接。但是若出现同时关闭连接请求时,通信双方均从 ESTABLISHED 状态转换为 FIN_WAIT_1 状态。
任意一方收到对方发来的 FIN 报文段后,其状态均由 FIN_WAIT_1转变到 CLOSING 状态,并发送最后的 ACK 数据段。当收到最后的 ACK 数据段后,状态转变化 TIME_WAIT,
在等待 2MSL 时间后进入到 CLOSED 状态,最终释放整个 TCP 传输连接。其过程入下: