UNP卷一学习笔记:TCP状态

Posted printfnothing

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UNP卷一学习笔记:TCP状态相关的知识,希望对你有一定的参考价值。

搞linux后台开发,必须掌握Stevens的著作《UNIX网络编程》里提及的大量知识点,所以我特意从网上购买了一套(O(∩_∩)O)。

面对厚厚的卷一,不实践,不记笔记,我觉得很难有所提升,故我决定将自己看书时候觉得重要的知识点和一些总结记录下来。

今天的笔记是关于TCP状态的。

TCP状态变迁主要发生在三次握手或四次挥手的时候,而且在此期间客户端client和服务器server的TCP状态变化是不同的,大家如果有兴趣可以去google或者看原书,这里我就不再画他们的状态图了。不过有些状态需要我们去研究下它们的意义,以及计算机在此状态下在干什么。

先来看三次握手和四次挥手阶段client和server的TCP状态含义。

三次握手阶段:

正常三次握手情况下

    client的tcp状态变迁应该是:CLOSED→SYN_SENT→ESTABLISHED

    server的tcp状态变迁应该是:CLOSED→LISTEN→SYN_RCVD→ESTABLISHED

你也许会奇怪,那为什么在client的tcp状态中出现了SYN_RCVD状态,在server的tcp状态中出现了SYN_SENT状态?

一般来说,我们把主动率先发起连接请求的一方叫做client,而被动接受连接请求的一方叫做server。那么有没有可能是双方同时主动发起连接请求呢?

这个是可能的,但是非常罕见,并且如果是双方同时发起连接请求,三次握手会变成四次


此时A、B双方既是client也是server,任何一方不会出现LISTEN状态。


再来看四次挥手阶段

在四次挥手阶段,TCP的状态变迁已经不再根据client还是server进行区分,而是看是谁率先主动发起关闭请求,谁被打接收关闭请求了。也就是说client可能是主动关闭的一方,也可能是被打关闭的一方,server同理。

这里需要说明下FIN报文的含义。FIN报文的含义表面看是一方发给另一方的关闭请求,但是更具体的含义是告诉对方自己已经没有数据要发送,如果对方也没有新数据要发送给自己,那么本次连接便可终止,双方tcp状态回到CLOSED。这也解释了为什么主动关闭方会出现FIN_WAIT_1和FIN_WAIT_2的状态。

FIN_WAIT_1和FIN_WAIT_2状态表明主动关闭方在等待被动关闭方发送完所有数据,在等待被动关闭方发送它的FIN报文;而被动关闭的一方,在发送给主动关闭方FIN报文前,一直处于CLOSE_WAIT状态。CLOSE_WAIT状态表明被动关闭方正在等待上层应用程序关闭,一旦应用程序关闭,被动关闭方将发送FIN报文给主动关闭方,而自己的TCP状态转为LAST_ACK,等待主动关闭方的确认。

至于CLOSING状态,其实类似于三次握手阶段的同时打开现象,它是在四次挥手阶段双方几乎同时主动关闭。

最后着重说明下TIME_WAIT的意义:

(1)可靠的实现TCP的全双工连接的终止

    被动关闭方处于LAST_ACK或者CLOSING状态时,会等待主动关闭方发来(对自己先前发送的FIN报文的)确认,如果确认丢失,被动关闭方会重发先前的FIN报文给主动关闭方,若没有TIME_WAIT状态,或者TIME_WAIT状态不够长,那么主动关闭方在CLOSED状态时会忽视新接收到的FIN报文,导致被动关闭方不能可靠的关闭。

(2)允许老的重复分组在网络中消逝

    由于路由选择等原因,网络中会残留双方先前通信的旧报文分组。如果在这些旧的重复报文分组消逝前,完全关闭了主动方的端口,也即端口处于CLOSED的状态,若此时又在此端口上新开一个连接,恰巧那些旧的报文分组又刚好到达,那么计算机就会把这些报文分组当成是新连接的分组,会导致解析错误。所以为了避免这一错误,通常将TIME_WAIT持续时间设置成MSL时间的2倍,这样足以让那些旧的报文分组在存活MSL时间后就消逝。

以上是关于UNP卷一学习笔记:TCP状态的主要内容,如果未能解决你的问题,请参考以下文章

UNP卷一学习笔记:TCP服务器常见故障

UNP卷一学习笔记:TCP服务器常见故障

UNP卷一学习笔记:基本UDP套接字编程

UNP卷一学习笔记:基本UDP套接字编程

UNP卷一学习笔记:高级I/O函数

UNP卷一学习笔记:高级I/O函数