TCP的11种状态
为了逻辑更加清晰,假设主动打开连接和关闭连接皆为客户端,被动打开连接和关闭连接皆为服务端
-
客户端独有的:(1)SYN_SENT (2)FIN_WAIT1 (3)FIN_WAIT2 (4)CLOSING (5)TIME_WAIT
-
服务器独有的:(1)LISTEN (2)SYN_RCVD (3)CLOSE_WAIT (4)LAST_ACK 。
-
共有的:(1)CLOSED (2)ESTABLISHED 。
1. LISTEN(服务端)
首先服务端需要打开一个 socket 进行监听,状态为LISTEN。
有提供某种服务才会处于LISTENING状态, TCP状态变化就是某个端口的状态变化,提供一个服务就打开一个端口,例如:提供www服务默认开的是80端口,提供ftp服务默认的端口为21,当提供的服务没有被连接时就处于LISTENING状态。FTP服务启动后首先处于侦听(LISTENING)状态。处于侦听LISTENING状态时,该端口是开放的,等待连接,但还没有被连接。就像你房子的门已经敞开的,但还没有人进来。
在客户端发送连接请求后,等待匹配的连接请求:
客户端通过应用程序调用connect进行active open.于是客户端tcp发送一个SYN以请求建立一个连接.之后状态置为SYN_SENT. /*The socket is actively attempting to establish a connection. 在发送连接请求后等待匹配的连接请求 */
2. SYN_SENT(客户端)
当请求连接时客户端首先要发送同步信号给要访问的机器,此时状态为SYN_SENT,同时会开启一个定时器,如果超时还没有收到ACK会重发 SYN。正常情况下SYN_SENT状态非常短暂。
例如要访问网站http://www.baidu.com ,如果是正常连接的话,用TCPView观察 IEXPLORE .EXE(IE)建立的连接会发现很快从SYN_SENT变为ESTABLISHED,表示连接成功。SYN_SENT状态快的也许看不到。
3. SYN-RECEIVED(服务端)
收到和发送一个连接请求后,等待对方对连接请求的确认。当服务器收到客户端发送的同步信号时,将标志位ACK和SYN置1发送给客户端,此时服务器端处于SYN_RCVD状态,如果连接成功了就变为ESTABLISHED,正常情况下SYN_RCVD状态非常短暂。
4. ESTABLISHED(共有)
ESTABLISHED状态是表示两台机器正在传输数据,观察这个状态最主要的就是看哪个程序正在处于ESTABLISHED状态。
5. FIN_WAIT_1(客户端)
主动关闭(active close)端应用程序调用close,于是其TCP发出FIN请求主动关闭连接,之后进入FIN_WAIT_1状态.
6. FIN-WAIT_2(客户端)
主动关闭端接到服务端的ACK后,就进入了FIN-WAIT-2。这就是著名的半关闭的状态了,这是在关闭连接时,客户端和服务器两次握手之后的状态。在这个状态下,应用程序还有接受数据的能力,但是已经无法发送数据,但是也有一种可能是,客户端一直处于FIN_WAIT_2状态,而服务器则一直处于WAIT_CLOSE状态,而直到应用层来决定关闭这个状态
7. CLOSE_WAIT(服务端)
服务端端TCP接到FIN后,就发出ACK以回应FIN请求(它的接收也作为文件结束符传递给上层应用程序),并进入CLOSE_WAIT.
8. TIME-WAIT(客户端)
在客户端接收到服务端的FIN后,客户端就发送ACK包,并进入TIME-WAIT状态
TIME_WAIT等待状态,这个状态又叫做2MSL状态,说的是在TIME_WAIT2发送了最后一个ACK数据报以后,要进入TIME_WAIT状态,这个状态是防止最后一次握手的数据报没有传送到对方那里而准备的(注意这不是四次握手,这是第四次握手的保险状态)。这个状态在很大程度上保证了双方都可以正常结束。
9. LAST-ACK(服务端)
服务端已经发送FIN以后等待客户端发送的ACK
被动关闭端一段时间后,接收到文件结束符的应用程序将调用CLOSE关闭连接。这导致它的TCP也发送一个 FIN,等待对方的ACK.就进入了LAST-ACK
10. CLOSING(客户端)
CLOSING状态在「同时关闭」的情况下出现。这里的同时关闭中的「同时」其实并不是时间意义上的同时,而是指的是在发送 FIN 包还未收到确认之前,收到了对端的 FIN 的情况。
11. closed(共有)
服务端在接受到ACK包后,就进入了closed的状态。连接结束