赞
踩
参考资料:TCP-IP详解
一个连接从开始建立到断开,经历了一连串的状态变化,这次主要分析下它的状态变迁图,首先上经典的状态变迁图
客户端的状态变迁:CLOSED-->SYN_SENT-->ESTABLISHED-->FIN_WAIT_1-->FIN_WAIT_2-->TIME_WAIT-->CLOSED
服务器的状态变迁:CLOSED-->LISTEN-->SYN_RCVD-->ESTABLISHED-->CLOSE_WAIT-->LAST_ACK--->CLOSED
CLOSED:这个状态不是一个真正的状态,是图中假想的一个起点或者是终点
LISTEN: 服务器等待连接过来的状态
SYN_SENT: 客户端发起连接(主动打开),变成此状态,如果SYN超时,或者服务器不存在直接CLOSED
SYN_RCVD:服务器收到SYN包的时候,就变成此状态,
ESTABLISHED:完成三次握手,进入连接建立状态,说明此时可以进行数据传输了
FIN_WAIT_1:客户端执行主动关闭,发送完FIN包之后便进入FIN_WAIT_1状态
FIN_WAIT_2:客户端发送FIN包之后,收到ACK,即进入此状态,其实就是半关闭的状态
TIME_WAIT:这个状态从图上看,有3中情况,从FIN_WAIT_2进入,客户端收到服务器发送过来的FIN包之后进入TIME_WAIT状态,有CLOSING状态进入,这是同时关闭的状态,同时发起FIN请求,同时接收并做了ACK的回复,从FIN_WAIT_1进入,收到对端的FIN,ACK,并回复ACK,这个地方感觉是,FIN和ACK是一块来的.
CLOSE_WAIT:接收到FIN之后,被动的一方进入此状态,并回复ACK
LAST_ACK:被动的一端发送FIN包之后 处于LAST_ACK状态
CLOSING:两边同时发出FIN请求
TIME_WAIT状态也成为2MSL状态,设立这个状态的是因为来保证可靠的实现TCP全双工的关闭,MSL指的是报文最大的生存时间。对于一个具体实现所给定的MSL值,处理原则是:当TCP执行一个主动关闭,并发回最后一个ACK,该连接必须在TIME_WAIT状态停留的时间为2MSL。这样可以让TCP再次发送最后的ACK,以防这个ACK丢失!
处于TIME_WAIT状态的连接,这个socket的四要素(Source IP,Source Port,Dest IP,Dest Port)不能被使用,只能在2MSL结束后才能再次被使用,其实这个地方,严格意义上来说是Port不能使用。
某些实现中,可以使用SO_REUSEADDR选项,可以让调用者对处于2MSL等待的本地端口进行赋值,但是我们将看到TCP原则上扔将避免使用仍处于2MSL连接中的端口。
对于客户端来讲,主动关闭是处于2MSL状态下,但是如果不bind对应的PORT其实看起来没什么影响的,因为下一次启动客户端,就应该分配到别的PORT了,但是对于bind Port的客户端或者服务器来讲,肯定是会报告Address already in use的错误。
有一个怪异的问题,别以为SO_REUSEADDR就万事大吉了,四要素处于2MSL,将不能被使用,尽管许多具体实现中允许一个进程重新使用仍处于2MSL等待的端口,但是TCP不能允许一个新的连接建立在相同的四元素上【有遇到过这样的问题】。
1. PC1 : Server启动,监听端口6666
2. PC2:Client connect to Server port 1098
3. 停止PC1服务器进程,这个时候PC1 的6666 和PC2的1098 处于2MSL状态
4. 在PC1上尝试使用port6666启动客户端进程,同时与PC2端口1098进行连接
5. 会有Address already in use的错误
6. 使用SO_REUSEADDR,继续做步骤5的动作
7. 仍然有Address already in use的错误
也就是说即使它能将它的本地端口设置为6666,但它仍然不能和PC2的1098进行连接,因为顶一个这个连接的四要素处于2MSL状态
复位报文其实主要说的就是RST标志被置位,无论何时一个报文段发往基准的连接出现错误,TCP都会发一个复位报文段,基准连接是指由目的IP地址和目的端口号以及源IP地址和源端口号指明的连接
a.到不存在的端口连接请求
这种状况是比较常见的,这个port没有被监听,但是有client去connect,这个时候TCP就会使用复位
b.异常终止一个连接
终止连接的正常的方式,就是调用close发送FIN包,这种的方式可以称为有序释放。但是有一个可能是发送一个复位报文而不是FIN来中途释放连接,这种状况就称为异常释放
优点:1.丢弃任何待发送的数据并立即发送复位报文。 2.RST的接收方会区分另一端执行的是异常关闭还是正常关闭
如何产生异常关闭? linger no close SO_LINGER提供了异常关闭的能力。
如果说对端被RST了,就会产生一个Connection reset by peer的错误!
c.检测半打开连接,对于半打开的连接,再次进行数据传输的时候,连接已经断开的一端也会通过RST包来终止连接。这部分主要在下面的文章中介绍,详细可以参考文章:TCP-IP详解:TCP半打开连接
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。