TCP/IP 协议笔记五 连接的建立与终止

一、连接的建立 

 

   1) 请求端(通常称为客户)发送一个 S Y N段指明客户打算连接的服务器的端口,以及初始序号(I S N,在这个例子中为1 4 1 5 5 3 1 5 2 1)。这个S Y N段为报文段1。

  2) 服务器发回包含服务器的初始序号的 S Y N报文段(报文段2)作为应答。同时,将确认序号设置为客户的I S N加1以对客户的S Y N报文段进行确认。一个S Y N将占用一个序号。
  3) 客户必须将确认序号设置为服务器的 I S N加1以对服务器的S Y N报文段进行确认(报文段3)。
  这三个报文段完成连接的建立。这个过程也称为三次握手( three-way handshake)。
 
二、连接的终止 

 

   建立一个连接需要三次握手,而终止一个连接要经过 4次握手。这由T C P的半关闭(h a l f -c l o s e)造成的。既然一个T C P连接是全双工(即数据在两个方向上能同时传递),因此每个方向必须单独地进行关闭。这原则就是当一方完成它的数据发送任务后就能发送一个 F I N来终止这个方向连接。当一端收到一个 F I N,它必须通知应用层另一端几经终止了那个方向的数据传送。发送F I N通常是应用层进行关闭的结果。

  收到一个F I N只意味着在这一方向上没有数据流动。一个 T C P连接在收到一个 F I N后仍能发送数据。而这对利用半关闭的应用来说是可能的,尽管在实际应用中只有很少的 T C P应用程序这样做。正常关闭过程如图 1 8 - 3所示。
     首先进行关闭的一方(即发送第一个 F I N)将执行主动关闭,而另一方(收到这个 F I N)执行被动关闭。通常一方完成主动关闭而另一方完成被动关闭,但双方都可以执行主动关闭。
  图1 8 - 3中的报文段4发起终止连接,它由Te l n e t客户端关闭连接时发出。这在我们键入 q u i t命令后发生。它将导致T C P客户端发送一个F I N,用来关闭从客户到服务器的数据传送。当服务器收到这个 F I N,它发回一个A C K,确认序号为收到的序号加 1(报文段5)。和S Y N一样,一个F I N将占用一个序号。同时 T C P服务器还向应用程序(即丢弃服务器)传送一个文件结束符。接着这个服务器程序就关闭它的连接,导致它的 T C P端发送一个F I N(报文段6),客户必须发回一个确认,并将确认序号设置为收到序号加1(报文段7)。
  图1 8 - 4显示了终止一个连接的典型握手顺序。我们省略了序号。在这个图中,发送F I N将导致应用程序关闭它们的连接,这些F I N的A C K是由T C P软件自动产生的。
  连接通常是由客户端发起的,这样第一个 S Y N从客户传到服务器。每一端都能主动关闭这个连接(即首先发送 F I N)。然而,一般由客户端决定何时终止连接,因为客户进程通常由用户交互控制,用户会键入诸如“ q u i t”一样的命令来终止进程。在图 1 8 - 4中,我们能改变上边的标识,将左方定为服务器,右方定为客户,一切仍将像显示的一样工作(例如在 1 4 . 4节中的第一个例子中就是由d a y t i m e服务器关闭连接的)。
 
三、状态变化 
  只有当S Y N _ R C V D状态是从L I S T E N状态(正常情况)进入,而不是从 S Y N _ S E N T状态(同时打开)进入时,从 S Y N _ R C V D回到L I S T E N的状态变迁才是有效的。这意味着如果我们执行被动关闭(进入L I S T E N),收到一个S Y N,发送一个带A C K的S Y N(进入S Y N _ R C V D),然后收到一个R S T,而不是一个A C K,便又回到LI S T E N状态并等待另一个连接请求的到来。
 
  T I M E _ WA I T状态也称为2 M S L等待状态。每个具体 T C P实现必须选择一个报文段最大生存时间M S L(Maximum Segment Lifetime)。它是任何报文段被丢弃前在网络内的最长时间。我们知道这个时间是有限的,因为 T C P报文段以I P数据报在网络内传输,而I P数据报则有限制
其生存时间的T T L字段。
  RFC 793 [Postel 1981c] 指出MSL为2分钟。然而,实现中的常用值是30秒,1分钟,或2分钟。
  对一个具体实现所给定的 M S L值,处理的原则是:当 T C P执行一个主动关闭,并发回最后一个A C K,该连接必须在 T I M E _ WA I T状态停留的时间为 2倍的M S L。这样可让T C P再次发送最后的A C K以防这个A C K丢失(另一端超时并重发最后的 F I N)。
  这种2 M S L等待的另一个结果是这个 T C P连接在2 M S L等待期间,定义这个连接的插口(客户的I P地址和端口号,服务器的 I P地址和端口号)不能再被使用。这个连接只能在 2 M S L结束后才能再被使用。
  遗憾的是,大多数 T C P实现(如伯克利版)强加了更为严格的限制。在 2 M S L等待期间,插口中使用的本地端口在默认情况下不能再被使用。我们将在下面看到这个限制的例子。
  某些实现和A P I提供了一种避开这个限制的方法。使用插口A P I时,可说明其中的S O _ R E U S E A D D R选项。它将让调用者对处于2 M S L等待的本地端口进行赋值,但我们将看到TCP原则上仍将避免使用仍处于2MSL连接中的端口。
  在连接处于2 M S L等待时,任何迟到的报文段将被丢弃。因为处于 2 M S L等待的、由该插口对(socket pair)定义的连接在这段时间内不能被再用,因此当要建立一个有效的连接时,来自该连接的一个较早替身( i n c a r n a t i o n)的迟到报文段作为新连接的一部分不可能不被曲解(一个连接由一个插口对来定义。一个连接的新的实例( i n s t a n c e)称为该连接的替身)。
  对于来自某个连接的较早替身的迟到报文段, 2 M S L等待可防止将它解释成使用相同插口对的新连接的一部分。但这只有在处于 2 M S L等待连接中的主机处于正常工作状态时才有效。如果使用处于2 M S L等待端口的主机出现故障,它会在 M S L秒内重新启动,并立即使用故障前仍处于2 M S L的插口对来建立一个新的连接吗?如果是这样,在故障前从这个连接发出而迟到的报文段会被错误地当作属于重启后新连接的报文段。无论如何选择重启后新连接的初始序号,都会发生这种情况。
  为了防止这种情况,RFC 793指出T C P在重启动后的M S L秒内不能建立任何连接。这就称为平静时间(quiet time)。
  只有极少的实现版遵守这一原则,因为大多数主机重启动的时间都比MSL秒要长
  在F I N _ WA I T _ 2状态我们已经发出了 F I N,并且另一端也已对它进行确认。除非我们在实行半关闭,否则将等待另一端的应用层意识到它已收到一个文件结束符说明,并向我们发一个F I N来关闭另一方向的连接。只有当另一端的进程完成这个关闭,我们这端才会从F I N _ WA I T _ 2状态进入T I M E _ WA I T状态。
  这意味着我们这端可能永远保持这个状态。另一端也将处于 C L O S E _ WA I T状态,并一直保持这个状态直到应用层决定进行关闭。
  许多伯克利实现采用如下方式来防止这种在F I N _ WA I T _ 2状态的无限等待。如果执行主动关闭的应用层将进行全关闭,而不是半关闭来说明它还想接收数据,就设置一个定时器。如果这个连接空闲1 0分钟7 5秒,T C P将进入C L O S E D状态。在实现代码的注释中确认这个实现代码违背协议的规范。
  
  我们已经介绍了T C P首部中的R S T比特是用于“复位”的。一般说来,无论何时一个报文段发往基准的连接( referenced connection)出现错误,T C P都会发出一个复位报文段(这里提到的“基准的连接”是指由目的 I P地址和目的端口号以及源 I P地址和源端口号指明的连接。这就是为什么RFC 793称之为插口)
  产生复位的一种常见情况是当连接请求到达时,目的端口没有进程正在听。对于 U D P,我们在6 . 5节看到这种情况,当一个数据报到达目的端口时,该端口没在使用,它将产生一个I C M P端口不可达的信息。而T C P则使用复位。
  到终止一个连接的正常方式是一方发送 F I N。有时这也称为有序释放(orderly release),因为在所有排队数据都已发送之后才发送 F I N,正常情况下没有任何数据丢失。但也有可能发送一个复位报文段而不是 F I N来中途释放一个连接。有时称这为异常释放(abortive release)。
  异常终止一个连接对应用程序来说有两个优点:(1)丢弃任何待发数据并立即发送复位报文段;(2)R S T的接收方会区分另一端执行的是异常关闭还是正常关闭。应用程序使用的A P I必须提供产生异常关闭而不是正常关闭的手段。
  使用s o c k程序能够观察这种异常关闭的过程。 Socket API通过“linger on close”选项(S O _ L I N G E R)提供了这种异常关闭的能力。我们加上 - L选项并将停留时间设为 0。这将导致连接关闭时进行复位而不是正常的 F I N。
  收到R S T的一方将终止该连接,并通知应用层连接复位。
  
  如果一方已经关闭或异常终止连接而另一方却还不知道,我们将这样的 T C P连接称为半打开(H a l f - O p e n)的。任何一端的主机异常都可能导致发生这种情况。只要不打算在半打开连接上传输数据,仍处于连接状态的一方就不会检测另一方已经出现异常。
  半打开连接的另一个常见原因是当客户主机突然掉电而不是正常的结束客户应用程序后再关机。这可能发生在使用 P C机作为Te l n e t的客户主机上,例如,用户在一天工作结束时关闭P C机的电源。当关闭P C机电源时,如果已不再有要向服务器发送的数据,服务器将永远不知道客户程序已经消失了。当用户在第二天到来时,打开 P C机,并启动新的Te l n e t客户程序,在服务器主机上会启动一个新的服务器程序。这样会导致服务器主机中产生许多半打开的T C P连接(在第2 3章中我们将看到使用T C P的k e e p a l i v e选项能使T C P的一端发现另一端已经消
失)。
  能很容易地建立半打开连接。在 b s d i上运行Te l n e t客户程序,通过它和s v r 4上的丢弃服务器建立连接。我们键入一行字符,然后通过 t c p d u m p进行观察,接着断开服务器主机与以太网的电缆,并重启服务器主机。这可以模拟服务器主机出现异常(在重启服务器之前断开以太网电缆是为了防止它向打开的连接发送 F I N,某些T C P在关机时会这么做)。服务器主机重启后,我们重新接上电缆,并从客户向服务器发送另一行字符。由于服务器的 T C P已经重新启动,它将丢失复位前连接的所有信息,因此它不知道数据报文段中提到的连接。 T C P的处理原则是接收方以复位作为应答。
  T C P首部可以包含选项部分(图 1 7 - 2)。仅在最初的T C P规范中定义的选项是选项表结束、无操作和最大报文段长度。在我们的例子中,几乎每个 S Y N报文段中我们都遇到过M S S选项。新的R F C,主要是RFC 1323 [Jacobson, Braden和Borman 1992],定义了新的T C P选项,

 

 每个选项的开始是1字节k i n d字段,说明选项的类型。k i n d字段为0和1的选项仅占1个字节。其他的选项在k i n d字节后还有l e n字节。它说明的长度是指总长度,包括 k i n d字节和l e n字节。

  设置无操作选项的原因在于允许发方填充字段为 4字节的倍数。如果我们使用 4 . 4 B S D系统进行初始化T C P连接,t c p d u m p将在初始的S Y N上显示下面T C P选项:
  <mss 512, nop, wscale 0, nop, nop, timestamp 146647 0>M S S选项设置为5 1 2,后面是N O P,接着是窗口扩大选项。第一个 N O P用来将窗口扩大选项填充为4字节的边界。同样, 1 0字节的时间戳选项放在两个 N O P后,占1 2字节,同时使两个 4字
节的时间戳满足4字节边界。
  其他k i n d值为4、5、6和7的四个选项称为选择A C K及回显选项。由于回显选项已被时间戳选项取代,而目前定义的选择 A C K选项仍未定论,并未包括在RFC 1323中,因此图1 8 - 2 0没有将它们列出。另外,作为 T C P事务的T / T C P建议也指明kind为11, 12和 13的三个选项。
posted @ 2021-01-22 20:40  无边落寞  阅读(302)  评论(0)    收藏  举报