TCP链接创建及关闭过程

1.什么是链接?编程

  TCP协议属于运输层协议,运输层协议是在端系统中,而不是在路由器中实现的,因此,这种链接不是一条电路,它的链接状态,彻底保存在两个端系统中.中间的网络元素,包括路由器和链路层交换机这些网络元素不会维持TCP的链接状态.一个进程往另外一端的某进程发送数据以前,必须先相互握手,即它们必须相互发送某些预备报文段,以创建确保数据传输的参数.缓存

2.链接的三次握手过程安全

 第一次握手:客户端首先向服务器端发送一个被称为SYN的特殊TCP报文段,此报文段的SYN比特位被置为1,另外客户端会随机选择一个初始序号client_seq并将此编号放置在TCPSYN报文段的序号字段中并发送给服务器服务器

 第二次握手:服务器收到此TCPSYN报文段后,提取出SYN字段,并为该链接分配TCP缓存和变量,而后向客户端发送容许链接的报文段SYNACK,此报文段中SYN比特位被置为1,而后该报文段的确认号字段被置为client_seq+1,序列号置为server_seq网络

    第三次握手:客户端在收到SYNACK以后,客户端也要给该链接分配缓存和变量,而后向服务器发送另外一个报文段,这最后一个报文段对服务器的容许链接的报文段进行了确认(将确认号置为server_seq+1).同时,由于链接已创建 ,SYN标志为此时为0并发

 要注意的是,以上三次握手过程当中,在前两个握手阶段,都不含有应用层的任何数据,而在第三个阶段中,可携带应用层的数据 .三次握手完成后,之后的每一个报文段,SYN比特位都被置为0,实际上,只有握手过程当中的第一二次握手,SYN比特位才为1.socket

 三次握手过程图标以下:函数

      

              (TCP三次握手过程)server

3.链接的关闭blog

  TCP链接须要三次握手,而关闭须要四次恢手,TCP链接的任一方都能主动发起关闭

  a.A方向B方发送一个特殊的报文段,此报文段FIN标志位被设为1.此时,A方进入FIN_WAIT_1状态,并关闭写通道

  b.B方收到A发来的带有FIN标志的报文段后,先发送ACK报文段,同时关闭读通道(也就是说如今再也不从这个链接上读取数据了,如今read会返回0),此时B将进入CLOSE_WAIT状态,再发送一个FIN标志位为1的报文段

  c.A方处于FIN_WAIT_1状态时,收到B方发来的ACK确认报文后,进入FIN_WAIT_2状态

  d.A方处于FIN_WAIT_2状态时,收到B方发来的带有FIN标志位为1的报文段后,进入TIME_WAIT状态,此状态维持的时间与具体实现相关,通常为2分钟.通过等待后,链接正式关闭,全部资源将被释放

     

  主动发起方,在TIME_WAIT后,才会完全关闭,被动关闭方,在对方的ACK到来后关闭

4.TCP的半关闭

  TCP提供了链接的一端在结束它的发送后还能接收来自另外一端数据的能力,这就是所谓的半链接.当向对方发送一个FIN给另外一端时,就代表本方已结束发送数据,但依然能够接收另外一端发来的数据,直到对方也发来了FIN.也就是说,在FIN_WAIT_1-FIN_WAIT_2这一段时间内,都处于半关闭状态.

  服务器和客户端应用程序判断对方是否已经关闭链接的方法是:read调用返回0(收到结束报文段).socket网络编程接口经过shutdown函数提供了对半关闭的支持.

5.CLOSE_WAIT状态

  当一方主动关闭链接时(经过close或shutdown系统调用向服务器发送结束报文段),另外一方经过返回确认ACK使链接进入CLOSE_WAIT状态。这个状态含义就是:等待主动关闭方应用程序关闭。一般,被动方也会当即给主动关闭方发送FIN报文段来关闭链接。

这将使链接转移到LAST_ACK状态 ,以等待主动关闭方对FIN报文段的最后一次确认,一旦确认完成,链接就完全关闭了。

6.TIME_WAIT状态

  主动关闭的一方,在收到对方发来的FIN后,并无直接进入CLOSED状态,而是转移到TIME_WAIT状态.在这个状态,主动关闭的一方要等待长为2MSL(报文段最大生存时间)的时间,

才能彻底关闭.MSL是TCP报文段在网络中的最大生存时间,RTF建议值是2min.

  time_wait状态存在的缘由有二:

  a.可靠地终止TCP链接

  b.保证让迟来的TCP链接报文段有足够的时间被识别并丢弃

  对于第一个缘由,若是主动关闭方收到对方发来的FIN后,发送给被动关闭方的ACK没有被正常收到,则被动关闭方会再次发送FIN,因此若是在TIME_WAIT状态时,对方没有再次发送FIN,则表示对方已经收到了ACK.已经正确关闭了.在Linux系统中, 一个TCP端口不能被同时打开屡次,当一个TCP链接处于TIME_WAIT状态时,将没法当即使用该链接占用着的端口.反过来,若是不存在TIME_WAIT状态,则应用程序可以当即创建一个和刚关闭的链接具备相同IP和端口的链接.这个链接可能会收到原来的链接的数据,这显然不该该发生,这就是time_wait状态存在的第二个缘由.

  另外,TCP报文段的最大生存时间是MSL,因此坚持2MSL时间的TIME_WAIT状态可以确保网络上两个传输方向上还没有被接收到的,迟到的TCP报文段都已经消失.所以一个具备相同IP和端口的链接就能够安全地创建,而绝对不会收到属于原来链接的应用数据.

  对于客户端来讲,一般不用担忧上面的TIME_WAIT致使不能绑定对应端口的问题,由于客户端通常使用系统自动分配的临时端口号,而因为随机性,临时端口号通常和程序上一次使用的端口号(还处于TIME_WAIT状态的那个链接使用的端口号)不一样,因此客户端能够当即重启.而若是是服务器主动关闭链接后异常终止,则由于它老是使用一个相同的端口号,因此由于TIME_WAIT状态将致使它不能当即重启,不过能够经过设置socket选项SO_REUSEADDR来强制进程当即使用TIME_WAIT状态的链接占用的端口.

相关文章
相关标签/搜索