TCP状态解释(3次握手,4次挥手)
young / / / 阅读量

TCP建立连接

三次握手

CLOSED:起始状态,无任何连接。
LISTEN:服务端建立socket之后需要listen进入LISTEN(侦听)模式,侦听来自远方的TCP连接请求。

SYN_SENT:客户端建立socket之后需要connect服务器,向服务端发送SYN=j(随机数)申请连接,然后会进入SYN_SENT状态。
SYN_RCVD:服务端在 侦听模式 下收到SYN后会向客户端回应ACK=j+1,同时发送SYN=k,然后进入SYN_RCVD状态。

ACK是确认标志,可以附带进别的消息中,将ACK附带进SYN中,所以只发送一个SYN/ACK。具体可以自行搜索,参考:TCP的确认系列——发送状态转换机
ESTABLISHED:客户端收到ACK后进行验证,同时回应服务端发来的SYN,返回ACK=k+1,然后进入ESTABLISHED状态。服务端收到最后一个ACK后验证,然后进入ESBABLESHED。表示双方的连接建立完成,可以进行数据传输。


TCP断开连接

四次挥手

一般由客户端主动断开连接,服务端只做被动连接。但是如果有必要,服务端也可主动断开连接。
FIN_WAIT_1:在ESTABLISHED(连接)状态下,主动断开连接会向对端发送FIN,然后进入FIN_WAIT_1状态。
CLOSED_WAIT:被动断开连接的一端收到FIN之后,会回应ACK,然后进入CLOSED_WAIT状态,在CLOSED_WAIT状态下,连接只能发送数据不能接收数据。
FIN_WAIT_2:主动断开连接的一端收到FIN的ACK回应后会进入FIN_WAIT_2状态。此时无法再发送数据但是可以接受数据。
LAST_ACK:被动断开连接的一端在缓冲区数据发送完成后会发送FIN然后进入LAST_ACK状态。如果程序健壮性较差,在socket收到文件结束符之后没有关闭socket,此处不会发出FIN,导致连接停留在CLOSED_WAIT&FIN_WAIT_2状态。
TIME_WAIT:主动断开连接的一端在收到对端的FIN后回应ACK然后进入TIME_WAIT。此状态下连接已断开,但为了避免最后一个ACK在网络中迷路,而导致的状态紊乱,端口会被保留2MSL的时长。
MSL(Maximum Segment Lifetime)——参考:什么是2MSL
CLOSED:在TIME_WAIT状态停留时间达到2
MSL之后进入CLOSED状态,表示无任何连接。
还有一种少见的断开连接的方式,两边同时主动断开连接,在这种情况下会有有一种其他状态——CLOSING状态,后面的文章链接TCP的连接和释放,里面有提及。

TCP的连接

TCP连接的建立采用客户服务器方式。TCP连接可分为通信双方一方发起连接和双方同时发起连接。

一方发起连接

假设A方为客服端,B为服务器端,由A向B发起建立连接请求。
B的服务器进程创建传输控制块TCB,准备接受客户进程的连接请求。然后服务器进程处于LISTEN状态,等待客服端的连接请求。
A打的TCP客服端进程创建控制块TCB,然后向B发送连接请求报文段。该报文的首部SYN=1,并且假设序号seq=x。TCP规定,该连接请求报文段不携带任何数据,但需要占用一个序号。A发送了连接请求报文后进入SYN-SENT状态。
B收到A的连接请求报文后,会向A返回连接接受报文。该报文的首部SYN=1,ACK=1,seq=y,ack=x+1。TCP也规定,连接接受报文段也不携带任何数据,但也需要占用一个序号。B发送该报文后立即进入SYN-RECD状态。
A收到B的连接接受报文后,还需要向B发送一个确认报文段。在该报文中ACK=1,seq=x+1,ack=y+1。TCP规定,在该报文段中可以携带数据,也可不携带数据。但,不携带数据时,不会消耗一个序号,也就会说下一个发送的报文段的序号仍为x+1。该报文段发送成功后,进入ESTAB-LISHED状态,。
B收到A的确认后,也进入ESTAB-ISHED状态。

同时发起连接

出现这种同时发起连接的情况可能性极小,但TCP仍然支持这种方式,这种方式没有客户端和服务器区分,一个既是客户端又是服务器。这种方式,双方同时发起连接请求报文,并进入SYN-SENT状态。当收到对方的连接请求报文后,马上发送一个连接接受报文,并马上进入SYN-REVD状态。当收到对方的连接接受报文后,进入ESTABISHED状态。

断开连接

断开连接也可以分为由连接一方发起断开连接请求和同时发起断开连接请求。

一方发起断开连接

A向B发起断开连接请求报文。该报文的首部中FIN=1,假设序列号seq=u,其为前面发送的报文段的数据的最后一个序列号加一。这是A进入FIN-WAI-1状态。TCP规定,断开连接请求报文不携带任何数据,但要消耗一个序列号。发送该报文之前会将缓冲区中的数据全部发送出去,该报文可以附加数据。

B在收到A的断开连接请求报文后,会发回一个确认报文。该报文的首部中ACK=1,ack=u+1,假设seq=v。B进入了CLOSE-WAIT状态。这时B会通知上层应用进程,这是A到B方向的连接释放了,表明A没有数据发给B了。这是可能会在该状态持续一段时间,等待B将没发送完的数据发送给A。这时A不能够发送数据给B,但A还可以接收数据。

A在收到B的确认报文后,会进入FIN-WAIT-2状态,等待B向A发送断开连接请求报文。

当B没有数据需要发送给A时,其会释放TCP连接。B向A发送断开连接请求报文。该报文的首部中FIN=1,ACK=1,ack=u+1,假设序列号为seq=w(因为可能在等待的这段时间里,B向A发送了一些数据)。这是B进入LAST-ACK状态。该报文也可以附加数据。

A收到B的断开连接请求报恩后,也会发回个确认报文。该报文中ACK=1,ack=w+1,seq=u+1。这时A进入TIME-WAIT状态。

B在收到A饿确认报文后,就彻底的断开了连接,并且会撤去相应的传输控制块。

快速断开连接:这种情况出现B发送给A断开连接确认报文,不仅为ACK而且FIN=1,也就是说在该确认报文中还包括了B的断开连接请求。这是A在收到该报文后,会给B发送一个确认报文,并进入TIME-WAIT状态。(相对于正常断开的4次握手,快速断开连接方式将第二次和第三次握手合成了一次)。

同时断开连接

两端应用层同时发出关闭命令时,两端均从 ESTABLISHED 变为 FIN_WAIT_1 。这将导致双方各发送一个 FIN ,两个 FIN 经过网络传送后分别到达另一端。收到 FIN 后,状态由 FIN_WAIT_1 变迁到 CLOSING ,并发送最后的 ACK 。当收到最后的 ACK 时,状态变化为 TIME_WAIT 状态。

支付宝捐赠
请使用支付宝扫一扫进行捐赠
微信捐赠
请使用微信扫一扫进行赞赏
有 0 篇文章