0x01 缘由
最近在结合linux 内核调试的方式,再深入理解socket编程相关知识,在应用开发过程中,把握socket的状态迁移,结合数据抓包分析,可以排查服务端相关异常。写这篇文章的目的是,发现我在调试过程中,写了一个简单的c/s通讯小程序,发现关闭server端候,立刻报端口被占用的错误,要等待一段时间自动删除。用netstat -ant | grep xxx 时发现端口处于TIME_WAIT状态。
0x02 状态迁移状态
这个图实际上是融合了tcp连接建立的三次握手过程(各种状态包的发送,即tcp状态标志的变化),以及数据传输过程和tcp四次挥手的过程。图形看起来实际比较费力,如果能够结合wireshark抓包分析工具,会更加清晰。
0x03 TIME_WATE状态
对应上图的状态,下面提示2MSL(MSL(Maximum Segment Lifetime)报文最长存活时间)超时。可以解析我章节一种的问题。
为什么需要这个状态呢?
1.为了保证A发送的最后一个ACK报文能够到达B。这个ACK报文段有可能丢失,因而使处在LAST-ACK状态的B收不到对已发送的FIN+ACK报文段的确认。B会超时重传这个FIN+ACK报文段,而A就能在2MSL时间内收到这个重传的 FIN+ACK报文段。如果A在TIME-WAIT状态不等待一段时间,而是在发送完ACK报文段后就立即释放连接,就无法收到B重传的FIN+ACK报文段,因而也不会再发送一次确认报文段。这样,B就无法按照正常的步骤进入CLOSED状态。
2.A在发送完ACK报文段后,再经过2MSL时间,就可以使本连接持续的时间所产生的所有报文段都从网络中消失。这样就可以使下一个新的连接中不会出现这种旧的连接请求的报文段。
0x04 总结
应为TIME_WATE和CLOSE_WATE导致的一些服务端生产环境的问题较多,如果不学习相关原理,可能不知道真正的原因,引用两个地址:http://www.cnblogs.com/sunxucool/p/3449068.html、http://blog.csdn.net/yohoph/article/details/41512935