计算机网络—— 运输层:TCP的连接建立和连接释放

Posted 大彤小忆

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了计算机网络—— 运输层:TCP的连接建立和连接释放相关的知识,希望对你有一定的参考价值。

计算机网络系列内容的学习目录 → \\rightarrow 谢希仁计算机网络学习系列内容汇总

8. TCP的连接建立和连接释放

8.1 TCP的连接建立

  ■ TCP是面向连接的协议,它基于运输连接来传送TCP报文段。
  ■ TCP运输连接的建立和释放是每一次面向连接的通信中必不可少的过程。
  ■ TCP运输连接有以下三个阶段:
    ⋄ \\diamond 1. 建立TCP连接
    ⋄ \\diamond 2. 数据传送
    ⋄ \\diamond 3. 释放TCP连接

在这里插入图片描述
  ■ TCP的运输连接管理就是使运输连接的建立和释放都能正常地进行。
  ■ TCP的连接建立要解决以下三个问题
    ⋄ \\diamond 1. 使TCP双方能够确知对方的存在;
    ⋄ \\diamond 2. 使TCP双方能够协商一些参数(如最大窗口值、是否使用窗口扩大选项和时间戳选项以及服务质量等);
    ⋄ \\diamond 3. 使TCP双方能够对运输实体资源(如缓存大小、连接表中的项目等)进行分配。
  ■ TCP使用“三报文握手”建立连接
  接下来看一下TCP使用三报文握手建立连接的具体过程。如下图是两台要基于TCP进行通信的主机,其中一台主机中的某个应用进程主动发起TCP连接建立,称为TCP客户。另一台主机中被动等待TCP连接建立的应用进程,称为TCP服务器。我们可以将TCP建立连接的过程比喻为“握手”,“握手”需要在TCP客户和服务器之间交换三个TCP报文段。最初,两端的TCP进程都处于关闭状态。

在这里插入图片描述
  一开始,TCP服务器进程首先创建传输控制块,用来存储TCP连接中的一些重要信息,例如TCP连接表、指向发送和接收缓存的指针、指向重传队列的指针、当前发送和接收序号等。之后,就准备接受TCP客户进程的连接请求。此时,TCP服务器进程就进入监听状态,等待TCP客户进程的连接请求。

在这里插入图片描述
  TCP服务器进程是被动等待来自TCP客户进程的连接请求,而不是主动发起,因此称为被动打开连接

在这里插入图片描述
  TCP客户进程也是首先创建传输控制块,然后在打算建立TCP连接时向TCP服务器进程发送TCP连接请求报文段,并进入同步已发送状态。TCP连接请求报文段首部中的同步位SYN被设置为1,表明这是一个TCP连接请求报文段。序号字段seq被设置了一个初始值x作为TCP客户进程所选择的初始序号。请注意,TCP规定SYN被设置为1的报文段不能携带数据,但要消耗掉一个序号。
  由于TCP连接建立是由TCP客户进程主动发起的,因此称为主动打开连接

在这里插入图片描述
  TCP服务器进程收到TCP连接请求报文段后,如果同意建立连接,则向TCP客户进程发送TCP连接请求确认报文段,并进入同步已接收状态。该报文段首部中的同步位SYN和确认位ACK都设置为1,表明这是一个TCP连接请求确认报文段。序号字段seq被设置了一个初始值y作为TCP服务器进程所选择的初始序号。确认号字段ack的值被设置成了x+1,这是对TCP客户进程所选择的初始序号的确认。请注意,这个报文段也不能携带数据,因为它是SYN被设置为1的报文段,但同样要消耗掉一个序号。

在这里插入图片描述
  TCP客户进程收到TCP连接请求确认报文段后,还要向TCP服务器进程发送一个普通的TCP确认报文段,并进入连接已建立状态。该报文段首部中的确认位ACK被设置为1,表明这是一个普通的TCP确认报文段。序号字段seq被设置为x+1,这是因为TCP客户进程发送的第一个TCP报文段的序号为x,并且不携带数据,因此第二个报文段的序号为x+1。请注意,TCP规定普通的TCP确认报文段可以携带数据,但如果不携带数据,则不消耗序号。在这种情况下,所发送的下一个数据报文段的序号仍是x+1,确认号字段ack被设置为y+1,这是对TCP服务器进程所选择的初始序号的确认。

在这里插入图片描述
  TCP服务器进程收到该确认报文段后,也进入连接已建立状态。现在,TCP双方都进入了连接已建立状态。它们可以基于已建立好的TCP连接,进行可靠的数据传输。

在这里插入图片描述
  思考: 为什么TCP客户进程最后还要发送一个普通的TCP确认报文段呢?这是否多余呢?换句话说能否使用两报文握手建立连接呢?
  答案是并不多余,不能简化为两报文握手。
  举例说明,考虑这样一种情况:TCP客户进程发出一个TCP连接请求报文段,但该报文段在某些网络结点长时间滞留了,这必然会造成该报文段的超时重传。假设重传的报文段被TCP服务器进程正常接收,TCP服务器进程给TCP客户进程发送一个TCP连接请求确认报文段,并进入连接已建立状态。请注意,由于我们改为“两报文握手”,因此TCP服务器进程发送完TCP连接请求确认报文段后,进入的是连接已建立状态,而不像“三报文握手”那样进入同步已接收状态,并等待TCP客户进程发来针对TCP连接请求确认报文段的普通确认报文段。TCP客户进程收到TCP连接请求确认报文段后,进入TCP连接已建立状态,但不会给TCP服务器进程发送针对该报文段的普通确认报文段。现在,TCP双方都处于连接已建立状态,它们可以相互传输数据。之后,可以通过“四报文挥手”来释放连接,TCP双方都进入了关闭状态。一段时间后,之前滞留在网络中的那个失效的TCP连接请求报文段到达了TCP服务器进程,TCP服务器进程会误认为这是TCP客户进程又发起了一个新的TCP连接请求,于是给TCP客户进程发送TCP连接请求确认报文段,并进入连接已建立状态,该报文段到达TCP客户进程。由于TCP客户进程并没有发起新的TCP连接请求,并且处于关闭状态,因此不会理会该报文段。但TCP服务器进程已进入了连接已建立状态,它认为新的TCP连接已建立好了,并一直等待TCP客户进程发来数据,这将白白浪费TCP服务器进程所在主机的很多资源。
  综上所述采用三报文手而不是两报文握手来建立TCP连接,是为了防止已失效的连接请求报文段突然又传送到了TCP服务器进程,因而导致错误。

在这里插入图片描述
  例: 主机甲向主机乙发送一个(SYN=1,seq=11220)的TCP段,期望与主机乙建立TCP连接,若主机乙接受该连接请求,则主机乙向主机甲发送的正确的TCP段可能是( C )
     A. (SYN=0 ,ACK=o0, seq=11221, ack=11221)
     B. (SYN=1 ,ACK=1, seq=11220, ack=11220)
     C. (SYN=1,ACK=1, seq=11221, ack=11221)
     D. (SYN=0 , ACK=o, seq=11220, ack=11220)
    分析:

在这里插入图片描述
  所谓三次握手(Three-Way Handshake)即建立TCP连接,就是指建立一个TCP连接时,需要客户端和服务端总共发送3个包以确认连接的建立。在socket编程中,这一过程由客户端执行connect来触发,整个流程如下图所示:

在这里插入图片描述
  第一次握手 SYN=1,ACK=0: Client将标志位SYN置为1,随机产生一个值seq=J,并将该数据包发送给Server,Client进入SYN_SENT状态,等待Server确认。
  第二次握手 SYN=1,ACK=1: Server收到数据包后由标志位SYN=1知道Client请求建立连接,Server将标志位SYN和ACK都置为1,ack=J+1,随机产生一个值seq=K,并将该数据包发送给Client以确认连接请求,Server进入SYN_RCVD状态。
  第三次握手 SYN=0,ACK=1 : Client收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给Server,Server检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,Client和Server进入ESTABLISHED状态,完成三次握手,随后Client与Server之间可以开始传输数据了。

  SYN攻击: 在三次握手过程中,Server发送SYN-ACK之后,收到Client的ACK之前的TCP连接称为半连接(half-open connect),此时Server处于SYN_RCVD状态,当收到ACK后,Server转入ESTABLISHED状态。SYN攻击就是Client在短时间内伪造大量不存在的IP地址,并向Server不断地发送SYN包,Server回复确认包,并等待Client的确认,由于源地址是不存在的,因此,Server需要不断重发直至超时,这些伪造的SYN包将产时间占用未连接队列,导致正常的SYN请求因为队列满而被丢弃,从而引起网络堵塞甚至系统瘫痪。

8.1.1 课后练习

  1. TCP采用三报文握手建立连接,其中第一个报文首部中的同步标志位SYN和确认标志位ACK的取值分别是( C )
    A. 0,0  B. 0,1  C. 1,0  D. 1,1
   分析: TCP采用三报文握手建立连接,其中第一个报文首部中的同步标志位SYN和确认标志位ACK的取值分别是1,0。

  2. TCP采用三报文握手建立连接,其中第二个报文首部中的同步标志位SYN和确认标志位ACK的取值分别是( D )
    A. 0,0  B. 0,1  C. 1,0  D. 1,1
   分析: TCP采用三报文握手建立连接,其中第二个报文首部中的同步标志位SYN和确认标志位ACK的取值分别是1,1。

  3. TCP采用三报文握手建立连接,其中第三个报文是
( C )
    A. TCP连接请求  B. 对TCP连接请求的确认  C. 对TCP连接请求确认的确认  D. TCP普通数据
   分析: TCP采用三报文握手建立连接,其中第三个报文是对TCP连接请求确认的确认。

  4. 主机甲向主机乙发送一个(SYN=1, seq=100)的TCP段,期望与主机乙建立TCP连接,若主机乙接受该连接请求,则主机乙向主机甲发送的正确的TCP段可能是( D )
    A. (SYN=0, ACK=0, seq=101, ack=101)
    B. (SYN=1, ACK=1, seq=100, ack=100)
    C. (SYN=0, ACK=0, seq=123, ack=123)
    D. (SYN=1, ACK=1, seq=123, ack=101)
   分析: 主机甲向主机乙发送一个(SYN=1, seq=100)的TCP段,期望与主机乙建立TCP连接,若主机乙接受该连接请求,则主机乙向主机甲发送的正确的TCP段可能是,SYN=1,ack=101。

  5. 主机甲发起与主机乙的TCP连接,主机甲选择的初始序号为200,如果三报文握手建立连接过程中最后一个报文不携带数据载荷,则TCP连接建立成功后主机甲给主机乙发送的第一个数据报文段的序号为( C )
    A. 199  B. 200  C. 201  D. 202
   分析: 主机甲发起与主机乙的TCP连接,主机甲选择的初始序号为200,如果三报文握手建立连接过程中最后一个报文不携带数据载荷,则TCP连接建立成功后主机甲给主机乙发送的第一个数据报文段的序号为201。

8.2 TCP的连接释放

  ■ TCP通过“四报文挥手”来释放连接

  接下来举例说明数据传输结束后,TCP通信双方都可以释放连接。现在,TCP客户进程和TCP服务器进程都处于连接已建立状态
  假设使用TCP客户进程的应用进程通知其主动关闭TCP连接,TCP客户进程会发送TCP连接释放报文段,并进入终止等待1状态。该报文段首部中的终止位FIN和确认位ACK的值都被设置为1,表明这是一个TCP连接释放报文段。同时,也对之前收到的报文段进行确认。序号seq字段的值设置为u,它等于TCP客户进程之前已传送过的、数据的最后一个字节的序号加1。请注意,TCP规定终止位FIN等于1的报文段即使不携带数据也要消耗掉一个序号。确认号ack字段的值设置为v,它等于TCP客户进程之前已收到的、数据的最后一个字节的序号加1。
  TCP服务器进程收到TCP连接释放报文段后,会发送一个普通的TCP确认报文段并进入关闭等待状态。该报文段首部中的确认位ACK的值被设置为1,表明这是一个普通的TCP确认报文段。序号seq字段的值设置为v,它等于TCP服务器进程之前已传送过的、数据的最后一个字节的序号加1,这也与之前收到的TCP连接释放报文段中的确认号匹配。确认号ack字段的值设置为u+1,这是对TCP连接释放报文段的确认。
  TCP服务器进程这时应通知高层应用进程,TCP客户进程要断开与自己的TCP连接。此时从TCP客户进程到TCP服务器进程这个方向的连接就释放了,这时的TCP连接属于半关闭状态,也就是TCP客户进程已经没有数据要发送了。但TCP服务器进程如果还有数据要发送,TCP客户进程仍要接收,也就是说从TCP服务器进程到TCP客户进程这个方向的连接并未关闭,这个状态可能会持续一段时间。

在这里插入图片描述
  TCP客户进程收到TCP确认报文段后就进入终止等待2状态,等待TCP服务器进程发出的TCP连接释放报文段。若使用TCP服务器进程的应用进程已经没有数据要发送了,应用进程就通知其TCP服务器进程释放连接。由于TCP连接释放是由TCP客户进程主动发起的,因此TCP服务器进程对TCP连接的释放称为被动关闭连接
  TCP服务器进程发送TCP连接释放报文段并进入最后确认状态,该报文段首部中的终止位FIN和确认位ACK的值都被设置为1,表明这是一个TCP连接释放报文段,同时也对之前收到的报文段进行确认。现在假定序号seq字段的值为w,这是因为在半关闭状态下TCP服务器进程可能又发送了一些数据。确认号ack字段的值为u+1,这是对之前收到的TCP连接释放报文段的重复确认。
  TCP客户进程收到TCP连接释放报文段后,必须针对该报文段发送普通的TCP确认报文段,之后进入时间等待状态。该报文段首部中的确认位ACK的值被设置为1,表明这是一个普通的TCP确认报文段。序号seq字段的值设置为u+1,这是因为TCP客户进程之前发送的TCP连接释放报文段虽然不携带数据,但要消耗掉一个序号。确认号ack字段的值设置为w+1,这是对所收到的TCP连接释放报文段的确认。
  TCP服务器进程收到该报文段号就进入关闭状态,而TCP客户进程还要经过两倍的MSL后才能进入关闭状态。MSL的意思是最长报文段寿,RFC793建议2分钟。

在这里插入图片描述
  也就是说,TCP客户进程进入时间等待状态后,还要经过4分钟才能进入关闭状态。这完全是从工程上来考虑的,对于现在的网络,MSL取为2分钟可能太长了,因此TCP允许不同的实现,可根据具体情况使用更小的MSL值。
  那么TCP客户进程在发送完最后一个确认报文段后,为什么不直接进入关闭状态,而是要进入时间等待状态,2MSL后才进入关闭状态?这是否有必要呢?
  来看这种情况,TCP服务器进程发送TCP连接释放报文段后进入最后确认状态,TCP客户进程收到该报文段后发送普通的TCP确认报文段,并进入关闭状态,而不是时间等待状态。然而该TCP确认报文段丢失了,这必然会造成TCP服务器进程对之前所发送的TCP连接释放报文段的超时重传,并仍处于最后确认状态。重传的TCP连接释放报文段到达TCP客户进程,由于TCP客户进程属于关闭状态,因此不理睬该报文段。这必然会造成TCP服务器进程反复重传,TCP连接释放报文段并一直处于最后确认状态,而无法进入关闭状态。因此,时间等待状态以及处于该状态2MSL的时长可以确保TCP服务器进程可以收到最后一个TCP确认报文段,而进入关闭状态。另外,TCP客户进程在发送完最后一个TCP确认报文段后,再经过2MSL时长,就可以使本次连接持续时间内所产生的所有报文段都从网络中消失,这样就可以使下一个新的TCP连接中不会出现旧连接中的报文段。

在这里插入图片描述
  以上就是TCP通过“四报文挥手”释放连接的过程。

  ■ TCP中保活计时器的作用。

  设想这样一种情况:TCP双方已经建立了连接,后来TCP客户进程所在的主机突然出现了故障。显然,TCP服务器进程以后就不能再收到TCP客户进程发来的数据。因此,应当有措施使TCP服务器进程不要再白白等待下去,换句话说,TCP服务器进程应该如何发现这种情况呢?

在这里插入图片描述
  方法就是使用饱和计时器。TCP服务器进程每收到一次TCP客户进程的数据,就重新设置并启动饱和计时器。若保活计时器定时周期内未收到TCP客户进程发来的数据,则当保活计时器到时后,TCP服务器进程就向TCP客户进程发送一个探测报文段,以后每隔75秒钟发送一次。若一连发送10个探测报文段后仍无TCP客户进程的响应,TCP服务器进程就认为TCP客户进程所在主机出了故障,接着就关闭这个连接。

  ■ TCP服务器进程每收到一次TCP客户进程的数据,就重新设置并启动保活计时器(2小时定时)。
  ■ 若保活计时器定时周期内未收到TCP客户进程发来的数据,则当保活计时器到时后,TCP服务器进程就向TCP客户进程发送一个探测报文段,以后则每隔75秒钟发送一次。若一连发送10个探测报文段后仍无TCP客户进程的响应,TCP服务器进程就认为TCP客户进程所在主机出了故障,接着就关闭这个连接。

8.2.1 课后练习

  1. TCP的通信双方,有一方发送了FIN标志位为1的报文段,表示( B )
    A. 将断开通信双方的TCP连接
    B. 单方面释放连接,表示本方已经无数据发送,但可以接收对方的数据
    C. 中止数据发送,双方都不能发送数据
    D. 连接被重新建立
   分析: TCP的通信双方,有一方发送了FIN标志位为1的报文段,表示单方面释放连接,表示本方已经无数据发送,但可以接收对方的数据。

  2. 假设TCP客户与TCP服务器的通信已经结束,TCP客户与TCP服务器之间端到端的平均往返时间为RTT,在t时刻TCP客户请求断开连接,则从t时刻起,TCP服务器释放该连接的最短时间是( C )
    A. 0.5个RTT
    B. 1个RTT
    C. 1.5个RTT
    D. 2个RTT
   分析: 假设TCP客户与TCP服务器的通信已经结束,TCP客户与TCP服务器之间端到端的平均往返时间为RTT,在t时刻TCP客户请求断开连接,则从t时刻起,TCP服务器释放该连接的最短时间是1.5个RTT。

以上是关于计算机网络—— 运输层:TCP的连接建立和连接释放的主要内容,如果未能解决你的问题,请参考以下文章

计算机网络入门基础篇——运输层

计算机网络入门基础篇——运输层

计算机网络湖科大微课堂笔记 p64-66 TCP的运输连接管理:TCP的连接建立与释放TCP报文段的首部格式

计算机网络 运输层(下)

计算机网络 运输层(下)

TCP连接的建立与释放(三次握手与四次挥手)