TCP/IP一直是一知半解的,这段时间终于是看了有关知识的,然后被里面的各种概念给搞的很糊涂,仅以此篇文章记录我对TCP/IP状态图的整理与理解。如果有不对的地方欢迎大家指出。
先上状态图:
来源:TCP/IP详解 卷一 中文版(http://docs.52im.net/extend/docs/book/tcpip/vol1/18/)
注:
-
有的文章里状态图里没有5这条线
但是在TCP/IP协议详解 卷一中有如下的描述:
名词解释
Socket:中文名称:插口。 一个IP地址和一个端口号合称Socket(RFC793)。
SocketPair:插口对,包含客户IP地址、客户端口号、服务器IP地址和服务器端口号的四元组。
一个SocketPair可唯一确定互联网络中每个TCP连接的双方。
打开:TCP建立连接。
关闭:TCP断开连接。
主动与被动:TCP打开/关闭发起者是主动,响应打开/关闭是被动。
客户端与服务器:这里我的理解是客户端与服务器是相对的概念,在TCP连接中,理论上一方都可以向另一方进行打开和关闭。例如有2个主机A和B,如果A请求B建立TCP连接,那么在此次TCP打开的过程中A就是客户端,B就是服务器,同理:如果是B请求A建立TCP连接,那么这个时候A就是服务器,B就是客户端,所以说客户端和服务器在状态图中是一个相对的概念。在不考虑同时打开,同时关闭的情况下(这两个等会儿单独讨论),有如下的几种TCP打开-关闭的可能:
- A主动打开,B被动打开,A主动关闭,B被动关闭。
- A主动打开,B被动打开,B主动关闭,A被动关闭。
- B主动打开,A被动打开,A主动关闭,B被动关闭。
- B主动打开,A被动打开,B主动关闭,A被动关闭。
也就是说在一次打开或者关闭的状态过程中,谁主动谁就是客户端,谁被动谁就是服务器。在此篇文章后面的描述中,客户端就是主动的主机,服务器就是被动的主机。
状态解释
CLOSED:这个没什么好说的了,表示初始状态,TCP连接的初始状态就是关闭状态。
LISTEN:这个也是非常容易理解的一个状态,表示服务器端的某个SOCKET处于监听状态,可以接受连接了。
SYN_RCVD:这个状态(状态图中的SYN收到)表示接受到了SYN报文,在正常情况下,这个状态是服务器端的SOCKET在建立TCP连接时的三次握手会话过程中的一个中间状态,很短暂,基本上用netstat你是很难看到这种状态的,除非你特意写了一个客户端测试程序,故意将三次TCP握手过程中最后一个ACK报文不予发送。因此这种状态时,当收到客户端的ACK报文后,它会进入到ESTABLISHED状态。
SYN_SENT:这个状态与SYN_RCVD遥想呼应,当客户端SOCKET执行CONNECT连接时,它首先发送SYN报文,因此也随即它会进入到了SYN_SENT状 态,并等待服务端的发送三次握手中的第2个报文。SYN_SENT状态表示客户端已发送SYN报文。
ESTABLISHED:这个容易理解了,表示连接已经建立了。
FIN_WAIT_1:这个状态要好好解释一下,其实FIN_WAIT_1和FIN_WAIT_2状态的真正含义都是表示等待对方的FIN报文。而这两种状态的区别 是:FIN_WAIT_1状态实际上是当SOCKET在ESTABLISHED状态时,它想主动关闭连接,向对方发送了FIN报文,此时该SOCKET即 进入到FIN_WAIT_1状态。而当对方回应ACK报文后,则进入到FIN_WAIT_2状态,当然在实际的正常情况下,无论对方何种情况下,都应该马 上回应ACK报文,所以FIN_WAIT_1状态一般是比较难见到的,而FIN_WAIT_2状态还有时常常可以用netstat看到。
FIN_WAIT_2:上面已经详细解释了这种状态,实际上FIN_WAIT_2状态下的SOCKET,表示半连接,也即有一方要求close连接,但另外还告诉对方,我暂时还有点数据需要传送给你,稍后再关闭连接。
TIME_WAIT:表示收到了对方的FIN报文,并发送出了ACK报文,就等2MSL后即可回到CLOSED可用状态了。如果FIN_WAIT_1状态下,收到了对方同时带 FIN标志和ACK标志的报文时,可以直接进入到TIME_WAIT状态,而无须经过FIN_WAIT_2状态。
CLOSING:这种状态比较特殊,实际情况中应该是很少见,属于一种比较罕见的例外状态。正常情况下,当你发送FIN报文后,按理来说是应该先收到(或同时收到)对方的 ACK报文,再收到对方的FIN报文。但是CLOSING状态表示你发送FIN报文后,并没有收到对方的ACK报文,反而却也收到了对方的FIN报文。什 么情况下会出现此种情况呢?其实细想一下,也不难得出结论:那就是如果双方几乎在同时close一个SOCKET的话,那么就出现了双方同时发送FIN报 文的情况,也即会出现CLOSING状态,表示双方都正在关闭SOCKET连接。
CLOSE_WAIT:这种状态的含义其实是表示在等待关闭。怎么理解呢?当对方close一个SOCKET后发送FIN报文给自己,你系统毫无疑问地会回应一个ACK报文给对 方,此时则进入到CLOSE_WAIT状态。接下来呢,实际上你真正需要考虑的事情是察看你是否还有数据发送给对方,如果没有的话,那么你也就可以 close这个SOCKET,发送FIN报文给对方,也即关闭连接。所以你在CLOSE_WAIT状态下,需要完成的事情是等待你去关闭连接。
LAST_ACK:这个状态还是比较容易好理解的,它是被动关闭一方在发送FIN报文后,最后等待对方的ACK报文。当收到ACK报文后,也即可以进入到CLOSED可用状态了。
TCP可能的过程
正常打开
正常打开是如图二中框1部分的交互图,也就是我们常说的TCP三次握手过程。
- 第一次握手:主动主机(客户端)发送SYN报文(报文1)给被动主机(服务器);
- 第二次握手:被动主机收到报文1后,发送ACK+SYN报文(报文2)给主动主机;
- 第三次握手:主动主机收到报文2后,发送ACK报文(报文3)给被动主机。
主动打开
主动发起TCP连接的,对应的图一状态图部分是:2->8
被动打开
被动接受TCP连接的,对应的图一状态图部分是:1->3->7
正常关闭
正常关闭是如图二中框2部分的交互图,也就是我们常说的TCP四次挥手过程。
参考资料:
TCP/IP详解 卷一 第18章(http://docs.52im.net/extend/docs/book/tcpip/vol1/18/)
https://www.cnblogs.com/qlee/archive/2011/07/12/2104089.html
网友评论