《unix网络编程》(3)TCP连接的建立和终止

来源:互联网 发布:linux中端口的欺骗 编辑:程序博客网 时间:2024/06/05 08:02

         TCP通过为每个字节关联一个序列号对所发送的数据进行排序。

         为了很好地理解connect、accept、close这三个函数并使用netstat程序调试TCP应用,必须了解TCP建立和终止并掌握TCP的状态转换图。

三次握手

        (1)服务器必须准备好接受外来连接。通常通过socket、bind和listen函数来完成,称之为被动打开(passive open)

        (2)客户通过connect发起主动打开(active open)。这导致客户TCP发送一个SYN同步分节,它告诉服务器客户将(待建立的)连接中发送的数据的初始序列号。通常,SYN不携带数据,其所在IP数据报仅包含IP首部、TCP首部以及可能有的TCP选项。

        (3)服务器确认(ACK)客户的SYN,同时自己发送一个SYN分节,它包含服务器将在同一个连接中发送数据的初始序列号。服务器在单个TCP分节中发送SYN和ACK。

        (4)客户必须确认服务器的SYN。


注意:

        服务器的ACK是客户SYN + 1,该ACK中的确认号是发送这个ACK的一端期待的下一个序列号;这是因为SYN占据一个字节的序列号空间;所以每个SYN的ACK中的确认号就是该SYN的初始序列号加1。

        同样,每个FIN的ACK中确认号为该FIN的序列号加1


TCP选项

每个SYN可以包含多个TCP选项。常见的如下。

       (1)MSS选项。发送SYN的一端使用该选项通知对端它的最大分节大小(maximum segment size),也就是本连接的每个TCP分节中愿意接受的最大数据量(TCP数据部分大小)。

       (2)窗口规模选项。TCP任何一端能通告对端的最大窗口大小为65535,因为TCP首部相应字段为16位。但是当今网络要求更大的窗口以便获得尽可能大的吞吐量。这个新选项指定TCP首部中的通告窗口必须扩大(左移)的位数(0~14),因此所提供的最大窗口接近1GB(65535 * 2 ^ 14)。使用该选项的前提是TCP连接两端都支持该选项。主动发起连接的一方在它的SYN中指定选项,只有在它从另一方的SYN中收到了这个选项后,该选项才会在以后的报文段中进行设置。

       (3)时间戳选项。该选项对于高速网络连接是必要的,它可以防止由丢而复现的分组可能造成的数据损坏(不用该选项,丢而复现的分组所承载的分节可能与再次使用相同序列号的真正分节发生混淆)。接收方在确认中返回该时间戳,从而允许发送方为每个收到的ACK计算RTT(”每个收到的ACK“而不是“每个报文段”,是因为TCP通常用一个ACK确认多个报文段)。

四次断开


       (1)某个应用进程先调用close,称该端为主动关闭(active close)。该端发送一个FIN,表示数据发送完毕。

       (2)接收到该FIN的对端执行被动关闭(passive clos)。这个FIN由TCP确认。它的接收也作为一个文件结束符传递给接收端应用进程(放在已经排队等待该应用进程接收的任何其他数据之后),因为FIN的接收意味着接收端应用进程在相应连接上再无额外数据可接收。

       (3)一段时间后,接收到这个文件结束符的应用进程将调用close关闭自己的套接字。这导致它的TCP也发送一个FIN。

       (4)接收这个最终FIN的原发送端TCP(执行主动关闭的一端)确认该FIN。


注意:

       FIN占据一个字节,因此每个FIN的ACK确认号是这个FIN的序列号加1。

       上边步骤2和3之间,从被动关闭一方到主动关闭一方数据流动是可能的。这称为半关闭

       无论客户还是服务器,任何一端都可以执行主动关闭。通常客户执行主动关闭,但某些协议(如HTTP/1.0)由服务器主动关闭


TCP状态转换图


TCP状态转换例子



TIME_WAIT状态

注意:

       主动关闭的一方会经历该状态,在该状态持续的时间是最长分节生命(maximum segment lifetime, MSL)的两倍,称为2MSL

       任何TCP实现都必须为MSL选择一个值。RFC 1122建议为2分钟,不过源自Berkeley的实现传统上为30秒,这意味着TIME_WAIT状态持续的时间为1分钟到4分钟。MSL是任何IP数据包能够在因特网中存活的最长时间。每个数据报包含一个跳限(hop limit)的8位字段,它最大值为255,这个跳数不是真正的时间限制但是仍然假设:具有最大跳限(255)的分组在网络中存活时间不可能超过MSL秒


迷途的重复分组(lost duplicate)

        也称为漫游的重复分组(wandering duplicate)。分组在网络中迷途通常是用于路由异常的结果。某个路由崩溃或某两个路由间某个链路断开时,路由协议要花费数秒或数分钟才能找到稳定的另一条通路。在这段时间内,可能发生路由循环,我们关心的分组陷入这样的循环。如果迷途的是TCP分片,在其迷途期间,发送端TCP超时并重传该分组,而重传的分组却通过某候选路径达到最终目的地。然而不久后(自迷途的分组开始最多MSL秒内)路由循环修复,最先迷途的分组最终被送到目的地。TCP必须能正确处理这些重复分组。


TIME_WAIT存在的两个理由

(1)可靠地实现TCP全双工连接的终止;

(2)允许老的重复分节在网络中消失。

         第一个理由通过”假设图2-5中最终的ACK丢失“来解释。服务器将重新发送最终的FIN,因此客户必须维护状态信息,以允许它重新发送最终的ACK。要是客户不维护状态信息,它将响应以一个RST(被服务器解释为错误)。TCP要结束所有必要的工作以彻底终止某连接上两个方向上的数据流(全双工关闭),那么TCP必须正确处理连接终止序列四个分节中任何一个丢失的情况。

         上述一段也说明了为什么执行主动关闭的一端是处于TIME_WAIT状态的那一端?因为可能不得不重传最终那个ACK的就是那一端。

         第二个理由,IP1、port1与IP2、port2建立了TCP连接,关闭该链接后。过一段时间,相同IP和端口建立另外一个连接,TCP必须防止上次连接中老的重复分组在新连接中再现。TCP处于TIME_WAIT状态就不可以发起新连接,TIME_WAIT状态持续2MSL,而分组存活最长时间只有MSL。这样的话就可以保证新TCP连接建立时,可能的旧的重复分组都在网络中消失了。


0 0
原创粉丝点击