第18章 TCP连接的建立与终止
18.8 同时打开
两个应用程序同时彼此执行主动打开的情况是可能的,尽管发生的可能性极小。每一方必须发送一个 S Y N,且这些S Y N必须传递给对方。这需要每一方使用一个对方熟知的端口作为本地端口。这又称为同时打开( simultaneous open)。
例如,主机A中的一个应用程序使用本地端口 7 7 7 7,并与主机B的端口8 8 8 8执行主动打开。主机B中的应用程序则使用本地端口 8 8 8 8,并与主机A的端口7 7 7 7执行主动打开。这与下面的情况不同:主机A中的Te l n e t客户程序和主机B中Te l n e t的服务器程序建立连接,与此同时,主机 B中的Te l n e t客户程序与主机A的Te l n e t服务器程序也建立连接。在这个 Te l n e t例子中,两个Te l n e t服务器都执行被动打开,而不是主动打开,并且 Te l n e t客户选择的本地端口不是另一端Te l n e t服务器进程所熟悉的端口。
T C P是特意设计为了可以处理同时打开,对于同时打开它仅建立一条连接而不是两条连接(其他的协议族,最突出的是 O S I运输层,在这种情况下将建立两条连接而不是一条连接)。当出现同时打开的情况时,状态变迁与图 1 8 - 1 3所示的不同。两端几乎在同时发送 S Y N,并进入S Y N _ S E N T状态。当每一端收到 S Y N时,状态变为S Y N _ R C V D(如图1 8 - 1 2),同时它们都再发S Y N并对收到的S Y N进行确认。当双方都收到 S Y N及相应的A C K时,状态都变迁为E S TA B L I S H E D。图1 8 - 1 7显示了这些状态变迁过程。
一个同时打开的连接需要交换 4个报文段,比正常的三次握手多一个。此外,要注意的是我们没有将任何一端称为客户或服务器,因为每一端既是客户又是服务器。
一个例子 尽管很难,但仍有可能产生一个同时打开的连接。两端必须几乎在同时启动,以便收到彼此的S Y N。只要两端有较长的往返时间就能保证这一点。这样我们将一端设置在主机 b s d i上,另一端则设置在主机 v a n g o g h . c s . b e r k e l e y . e d u上。由于两端之间有一条拨号链路S L I P,它的往返时间对保证双方同步收到 S Y N是足够长的(几百毫秒)。
一端(b s d i)将本地端口设置为 8 8 8 8(使用命令行选项 - b),并对另一端主机端口 7 7 7 7执行主动打开。
我们指明带- v标志的s o c k程序来验证连接两端的 I P地址和端口号。这个选项也显示每一端的M S S值。为证实两端确实在相互交谈,我们在每一端还输入一行字符,看它们是否会被送到另一端并显示出来。
图1 8 - 1 8显示了这个连接的段交换过程(我们删除了出现在来自 v a n g o g h第一个S Y N中的一些新的T C P选项,因为v a n g o g h使用4 . 4 B S D系统。将在1 8 . 1 0节介绍这些较新的选项)。注意两个S Y N(第1 ~ 2行)后跟着两个带A C K的S Y N(第3 ~ 4行)。它们将执行同时打开。
第5行显示了由b s d i发送给v a n g o g h的输入行“hello, world”,第6行对此进行确认。第7 ~ 8行对应另一方向的输入行“ and hi there”和确认。第9 ~ 1 2行显示正常的连接关闭。
许多伯克利版的T C P实现都不能正确地支持同时打开。在这些系统中,如果能够进行S Y N的同步接收,你将经历极多的报文段交换过程才能关闭它们。每个报文段交换过程包括每个方向上的一个 S Y N和一个 A C K。图1 8 - 1 2中从S Y N _ S E N T到状态 SYN_RCVD的变迁在许多TCP实现中很少测试过。