传输层协议TCP(2)

1 全双工的TCP连接

     TCP 连接一个需要特别指出的特征是:它是全双工的。也就是说,TCP 连接创建以后,双向可以同时发送数据,如下图所示:

        

        一般C/S模型和全双工都常用来形容TCP连接,但两者是不同的,差异如下:

  • (1)TCP Client/Server,指的是 TCP 连接创建过程中,谁是主动方,谁是被动方。
  • (2)TCP 连接的全双工,指的是 TCP 数据传输过程中,双方可以同时传输数据。

       两者所表达的场景是不同的。TCP的建立并不是C/S的模型,也可以是双方同时发起,这个时候也就不是经典3次握手中的三个报文了,也就不存在 TCP Client/Server 的概念,如图5-31所示(其中含有4个报文):

        

       需要说明的是,“同时”创建 TCP 连接,这里的“同时”,并不是指时间上的绝对同时,而是指的的:(1)双发都发送连接请求报文(SYN 报文);(2)在自己还没有收到对方发送的 SYN 报文时,自己已经发送给对方 SYN 报文了。这个对应到图5-31,就是 T1 时刻和 T2 时刻。

  • T1 时刻,A 发送1个 SYN 报文(报文1)给 B。T2 时刻,B 还没有收到 A 发送过来的报文1,但是它也发送了1个 SYN 报文(报文2)给 A。
  • T3、T4 时刻,则比较简单,A 和 B 都分别收到了对方发送过来的 SYN 报文。B 收到 A 发送过来的 SYN 报文以后,我们看图5-31的 T5 时刻,它跟图5-30一样,B 就发送相应的 <SYN、ACK> 报文。
  • 图5-31中,在 T4 时刻 A 收到了 B 发送过来的 SYN 报文,在 T6 时刻,A 收到了 B 发送过来的 <SYN、ACK>报文,然后再 T7 时刻发送了 ACK 报文。而在 T8 时刻,B 也收到了 A 发送过来的 ACK 报文。
  • 在 T6 时刻,A 收到了 B 发送过来的 ACK 报文(连接创建请求的确认报文),所以 A 的状态就是 ESTABLISHED(表明 A 认为它的 TCP 连接已经创建)。同理,在 T8 时刻,B 也收到了 A 发送过来的 ACK 报文,所以 B 的状态也是 ESTABLISHED。

       以上分析,从报文角度虽然发送了四次报文,但本质上还是三次握手。

2 TCP连接的关闭

TCP连接的关闭如下图所示:

       

       上图中也体现出了一端主动请求关闭,另一端被动接收的过程。实际上也有双方都同时发送FIN报文进行关闭TCP连接。创建了连接以后,中间经过了数据传输,然后 A 发现它的数据传输完毕,就给 B 发送了1个关闭连接的请求,也就是图5-33中的报文1除了前面讲TCP经典三次握手图中的第1个请求连接创建的报文(A 发送给 B)以外,其他所有报文都打了 ACK 标记(ACK = 1),这既是 TCP 的规定,也是 TCP 保证可靠传输的机制。下表为上图中发送的对应报文:

       1、上表中的 A 和 B 的状态,指的是 A、B 发送或接收报文以后的状态。如前所述,当 A 没有数据要发送给 B 时,它向 B 发送了1个关闭连接的请求报文(报文1)——FIN 标记为1(FIN = 1)——FIN 是 Finis(终结)的缩写。发送了报文1以后,A 进入 FIN-WAIT-1 状态,这有3层含义:

  • (1)A 不再发送数据
  • (2)但是它还可以接收数据
  • (3)A 的 TCP 连接还不能算关闭,它还要等待某件事情发送(接收某个报文)

       当 B 接收到 A 发送过来的“报文1”时,发现是 A 发送过来的“请求关闭连接”的报文,此时 B 的状态变为“CLOSE-WAIT”。这也有3层含义:

  • (1)B 清楚,A 不会发送数据了,但是 A 还可以接收数据
  • (2)B 自己还可以发送数据(因为 A 还可以接收数据)
  • (3)B 自己也在等着连接关闭,虽然它还不知道到底何时能够关闭这个连接,所以 B 此时的状态叫作“CLOSE-WAIT”;

     2、B 除了表达自己的“渴望”以外,也会立刻给 A 回以一个 ACK 报文(报文2),表示自己接受 A 关闭连接的请求。B 发送了“报文2”以后,它的状态仍然是“CLOSE-WAIT”——是的,它还在“渴望”。A 接收了“报文2”以后,它的状态变为“FIN-WAIT-2”——是的,它也还需要等待。像这种,A 已经没有数据要发送(也不能发送)但是能接收数据,而 B 还能发送数据的情况,称为“half-open”连接(半开连接),此时 A 的状态等于“FIN-WAIT-1”或“FIN-WAIT-2”,B 的状态等于“CLOSE-WAIT”。

     3、发送了“报文3”以后,B 的状态变为“LAST-ACK”。A 接收了“报文3”以后,它的状态变为“TIME-WAIT”,是的,它还需要等待,并会马上给 B 回以1个 ACK 报文(报文4):告诉B,它同意 B 的“关闭连接”的请求。

      4、B 接到 A 发送过来的“报文4”以后,可没有任何客气,马上将自己的状态变为“CLOSED”,即关闭连接。此时,B 已经关闭了连接,而 A 还在那里痴痴地等,一直等待2个“MSL”时间(表达的是1个 TCP 报文在网络中所能存在的最大时间,linux定义为30s),它才会将自己的状态设置为“CLOSED”,即关闭连接。

       以上所描述就是著名的 TCP “四次挥手”!与创建连接一样,关闭连接也存在双方“同时”关闭连接的场景。这只是“四次挥手”的一个变体,我们就不再详述,只是给出一个交互顺序图,如下图所示:

        

      上图只是一种变体,伴随着 A、B 所发送/接收报文的时间的不同,还会有其他顺序图。

3 TCP连接的状态机

      前面我们介绍了 TCP 连接的创建和关闭,本小节从 TCP 连接状态机的视角,对前述的内容做一个总结,如下图:

      

       方框里的内容,表示的是 TCP 连接的“状态”,比如“CLOSED”、“ESTABLISHED”等等。每个线条同时也对应着1对 <事件、响应>。<事件、响应>用虚线分隔,虚线上方表示事件,虚线下方表示响应。事件可能是 TCP 用户的动作,比如第1个线条所对应的事件就是“active OPEN”——这就是用户“active OPEN”了一个 TCP 连接。事件也可能是收到1个报文,比如第7个线条所对应的事件就是收到了1个“SYN”报文。响应可能是 TCP 内核的动作,比如第2个线条所对应的事件就是“delete TCB”——TCP 内核删除相应的 TCB 内存块。

        针对上图中的更全面的解释用下面几个表来说明:

      

       创建连接有两种方式,一种是“active OPEN”,另一种是“passive OPEN”。所谓“active OPEN”,其实就是创建1个 TCP Client 的连接(表面上是创建1个 socket,背后还需要创建 TCB 内存块),“passive OPEN”就是创建1个 TCP Server 端的连接(表面上是创建1个 socket,背后还需要创建 TCB 内存块)。对于 TCP Client 来说,它还需要主动发送连接创建请求报文,所以我们在第1条线条的响应中还看到了“send SYN”——发送 SYN 报文。而对于 TCP Sever 来说,它只需要监听就可以了。无论是 TCP Client 还是 TCP Server,此时它们还没有经过三次握手,两者之间的“连接”还没有对上,所以此时它们如果要关闭连接,则比较简单(不需要像“5.2.5 TCP 连接的关闭”所介绍的那样进行四次挥手),只需要直接“CLOSE”即可——而 CLOSE 的背后,就是删除对应的 TCB 内存块。

        继续往下分析:

      

       表中的“7、8、9”表达的就是著名的 TCP 三次握手。其中第8个线条中的响应,RFC 793标识的是“x”,表面上看,那什么都不用做,只是把状态迁移到“ESTABLISHED”即可。实际上,Host 内部还需要要创建 socket pair <s1, s2>,用以标识一对 TCP 连接。同时对于线条9,虽然 RFC 793 只标识了它的响应为“send ACK”,但是它的背后也是会创建 socket pair <s1, s2>。表5、6看起来不是按常理,实际上结合“5、6”,再结合“7、8、9”就会发现,它们所表达的其实是“同时创建 TCP 连接”的场景。

      上面两个表表示TCP连接 从无到有的创建过程,我们忽略掉中间的数据传输过程,那么剩下的就是数据传输结束以后的连接关闭过程,如下表。

      

       上表中表达的是 TCP 关闭连接的经典的“四次挥手”过程。表面上看线条11,什么都不用做,只需要等待对端发送“连接关闭请求”报文。实际上线条11、线条12,包括其他多个线条,其背后都需要创建1个定时器,因为总不能再那傻等。关于定时器、定时器超时等处理,后续再进行讲解。除了经典的“四次挥手”,TCP 还可以同时关闭连接,如下表所示:

        

        实际上“18、19”,在加上“13”,表达的就是“同时关闭 TCP 连接”的场景。线条19中的响应“x”,应该是真不需要做什么,除了启动 2MSL 定时器。

       无论是“四次挥手”,还是同时关闭(说明:本质上还是四次挥手),表5-10,5-11 表达的都是 TCP 连接创建好了以后(双方的状态都是“ESTABLISHED”)再关闭的场景。线条17表达的则是连接创建 OK 之前,就直接关闭。由于状态“SYN RECEIVED”表示的是“已经接到对端发送过来的连接请求报文”,所以不像线条2和线条4,线条17还是采取了相对“优雅”的动作:发送 FIN 报文(连接关闭请求报文)。

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值