首页 > 代码库 > tcp状态介绍和解释

tcp状态介绍和解释

  转眼间,从事服务器后台开发,已经快三年了,最近想多总结些东西,先从最基本的开始写起吧!

  在公司经历了两个框架的开发和重构,其中一个点,就是把服务器内部通信的机制,从UDP转为TCP。

  先讲下TCP的基本应用,还有其中的各个状态的情况。

  以下的TCP的状态流程图:

  wKioL1Q6ojLA0L_mAAL_U7tM3DM896.jpg  tcp建立连接,涉及的函数,主要有:

  服务端:socket bind listen  accept read write close

  客户端:socket connect write read close


其中,状态的变化主要有:

  syn_sent  syn_rcvd  established  fin_wait_1 fin_wait_2 close_wait time_wait last_ack   

  close 等各种状态。


tcp的建立和释放,简单说,就是三次握手和四次释放。

  三次握手的过程如下:

  1. 服务器调用socket,bind,listen,完成被动打开的过程,进入listen的状态;

  2. 客户端调用 connect 主动打开,向服务器发送syn1,进入syn_sent的状态;

  3. 服务器确认客户端的syn,同时自己发送一个syn2和ack,对客户端进行确认,进入syn_rcvd状态;

  4. 客户端接受到服务器发送的确认信息,进入establish状态,对服务器发送ack,服务器接受到ack,也进入到establish状态。

  这个过程中的包,通过tcpdump,抓取tcp连接的包时,经常就可以收到。


  四次释放的过程如下:

  1. 主动关闭的一方,调用close,发送fin M,表示不再发送数据,进入fin_wait_1状态;

  2. 被动关闭的一方,接收到fin M,进入close_wait状态,发送ack M+1;

  3. 主动关闭的一方,接收到 ack M+1,进入 fin_wait_2 状态;

  3. 被动关闭的一方,发送fin N,进入last_ack状态;

  4. 主动关闭的一方,接收到fin N, 进入time_wait状态,发送ack N+1, 被动关闭的一方接收到

     ack,进入 closed状态

  特殊的情况,是主动关闭的一方,发送fin M,没有接收到ack M+1,而是接收到 fin N, 表示对方

  也是要马上关闭数据,所以,马上转入closed状态。


  tcp的释放,为什么需要四次握手?

  如果一方执行主动关闭,只能保证本方不再发送数据,但是,无法确定是否要继续接收数据;

  

  为什么需要time_wait状态?

  1. 可靠地实现TCP全双工连接的终止

  网络数据的传输,肯定要考虑丢包的情况,如果最后一次ack丢失,被动关闭的一方,将重新发送

  它的FIN,因此主动关闭的一方,必须维持状态,允许自身重新发送最终的ACK。

  2. 允许老的重复分节在网络中消逝

  time_wait状态保持2msl的时间,msl指的是网络包在网络中存活的最长时间。

  假设没有time_wait状态,客户端A向服务器B发送数据,并进入closed状态。过一段时间,又用原来

  的端口和IP,重新建立连接,这时,之前在网络中传输的包,过一段时间,就可能被服务器接收到,

  而这个不是服务器期望接收到的。


  服务器为什么会处于close_wait状态?

  服务器接收到客户端主动关闭的请求,但是自身还没执行主动关闭,就会处于close_wait状态。

  如果服务器在recv数据包的时候,可能fin没有接收到,tcp代为回复了ack包,这时就进入close_wait

  状态。

  如果服务器上面,绝大多数连接都处于close_wait状态,那么很可能是因为服务器本身接收并处理完

  客户端的数据,没有close连接导致的。


  本文内容,参考了

  unix网络编程卷一的内容

  

本文出自 “思考沉淀” 博客,请务必保留此出处http://joezhengjinhong.blog.51cto.com/7791846/1563070

tcp状态介绍和解释