TCP

来源:百度文库 编辑:神马文学网 时间:2024/04/28 00:47:16
在阐述TCP连接建立和终止的原理时,课本使用了Telnet的diacard服务。这里对Telnet作一个简短回顾。
Telnet协议允许用户通过网络登录远程的计算机系统。这里所指的计算机系统不仅仅是基于Unix的,只要支持Telnet协议的系统都可登录。登录通常需要账号,但有些远程主机允许无账号登录。连接一经建立,你在终端的任何按键都将传递给远程主机。Telnet服务的Well-known端口号是23。
telnet命令:
telnet [options] [host [port]]
host可以是主机域名或者是IP地址
常用的两个选项 -a 尝试自动登录
-l 指定登录用户
telnet客户端有两种操作模式:输入模式(input mode)和命令模式(command mode)。不带参数直接执行telnet,终端显示“telnet>”提示符,这就是命令模式。在与服务器建立连接之后就进入输入模式。除了^],其他任何输入模式数据都将通过服务器telnet进程传输给服务器用作执行命令。”^]”是telnet的escape字符:从输入模式退出到命令模式(用Ctrl+]按键)。
几个telnet命令:
?或help 显示telnet命令列表
close或quit 关闭telnet连接
z 挂起telnet会话,返回本地主机,用fg重启telnet
tcpdump是网络数据采集分析工具。对tcpdump输出的简单介绍。
09:33:11.723111 IP 192.168.1.100.43136 > 210.32.0.10.telnet: S 470329474:470329474(0) win 5840
09:33:11.723111 时间,精确到1微秒
IP 192.168.1.100.43136 > 210.32.0.10.telnet:S源IP.端口号>目标IP.端口号:标志
470329474:470329474(0) 顺序号:隐含结尾顺序号(数据长度)。其中隐含的结尾顺序号出现在两种情况下:1)TCP段中包含数据字段;2)SYN,FIN或RST至少有一个打开
win 5840 窗口大小5840字节(注若每次都要显示绝对数序号,需要在tcpdump后加参数-S,否则后续的显示相对顺序号)
mss 1460 最大段大小 1460字节
(后面字段再补充)
建立TCP连接的步骤:
1.请求端(通常称为客户端,client)发出一个SYN段,该段中指明了它希望连接服务器的端口号,以及它自己的ISN;
2.服务器用它自己的SYN段响应客户端请求,也指明了它的ISN。同时,服务器用客户端的ISN+1确认收到客户端SYN;
3.客户端用服务器ISN+1确认收到服务器的SYN。
这通常称为三步握手(three-way handshake)
我们说发出第一个SYN的那端执行active open,而接收这个SYN,发出另一个SYN的那端执行passive open。
TCP连接终止
由于TCP提供全双工的服务,每个方向的数据流独立传输,因此需要对每个方向的传输进行单独关闭,这通常引起所谓的TCP半关闭(half-close)。原则是每一端在发送完数据后向另一端发出FIN。当TCP收到一个FIN后,它就通知应用程序这个方向的数据流已经结束。图

连接通常由客户端发起。但两端都可以主动关闭(active close)它,一般是由客户端来决定中止连接,因为它受用户交互。
与前文类似,称发出第一个FIN的那端执行active close,而另一端执行passive close。
在连接建立时可能超时,需要在若干时间后重试。
最大段大小(MSS)是TCP可以发送出去的最大数据块(chunk of data)。在连接建立时,每一端通告它的MSS。如果一端没有收到另一端的MSS通告,那么数据块大小将默认为536字节,IP数据报就是576字节(加20字节的IP头和20字节的TCP头)。
一般的,MSS越大越好,但要考虑分段(fragmentation)的因素。为避免分段,连接双方往往不发送超过较小MSS的数据块。但如果中间网络的MSS小于连接两端较小的MSS,比如两端MSS都是536,而中间网络的MSS是296,就将会发生分段,具体后续学习。
半关闭状态:连接一端停止了输出,但仍可以从另一端接收数据。
 
TCP状态迁移图

在ESTABLISHED状态,双方已经建立了连接,可以双向地进行数据传输。CLOSED实际上不是一个状态,这里假想它是状态的起点和终点。
如果状态SYN_RCVD是从LISTEN迁移过来的,那么它在收到RST(重置连接)后可以从SYN_RCVD返回到LISTEN;如果是从SYN_SENT迁移过来的,则不可再迁移到LISTEN状态。也就是说,我们执行被动打开(进入LISTEN状态),接收到一个SYN,并发送对它的ACK和另一个SYN,即进入SYN_RCVD状态。这时如果收到ACK,将进入ESTABLISHED状态;但要是收到RST,则又回到LISTEN状态,等待新的连接请求的到来。
TIME_WAIT状态也称为2MSL等待状态。在TCP实现中,必须给段最大生存时间(maximum segment lifetime ,MSL)指定一个值。这是TCP段在网络中存在而不被丢弃的最大时间量。但由于TCP段是封装在IP数据报中的,因此MSL又受TTL(IP数据报的存活时间)限制。在实际中TTL是基于跳(hop)的数目,而非计时器。
给MSL设置值的原则:TCP执行一个主动关闭,当它发送最后一个ACK后,连接必须在TIME_WAIT状态停留2倍MSL时间。这是为了在最后一个ACK丢失的情况下对其重发。处在TIME_WAIT状态的另一个影响是:在此连接中定义的socket对不能被重用,重用只能在2MSL状态结束以后。具体实例见课本P243-245。
当连接处于2MSL状态时,它的任何延迟的TCP段都将被丢弃。连接由socket对来定义,我们称一个连接的新的实例(instance)为该连接的一个化身(incarnation)。由于在2MSL状态时定义一个连接的socket对不能被重用,因此该连接前一个化身的TCP段是不会被后一个化身曲解(misinterprete)的。
通常是客户端执行主动关闭,进入TIME_WAIT状态,服务器执行被动关闭,不会进入TIME_WAIT状态。言下之意就是如果我们终止一个客户端,并立即重启一个相同客户端,那么新的客户端将不能使用相同的本地端口号。但这不成问题,因为客户端使用短暂的(ephemeral)端口,我们并不关心使用的本地端口号是多少。
但这对于服务器来说就不同了,因为服务器使用well-known端口号,比如telnet的23。如果我们终止一台已经建立连接的服务器,并立即重启,那么服务器将不能立即使用它的well-known端口号,因为这个端口号还是处在2MSL状态的连接的一部分。
考虑一种情况:主机有端口号处于2MSL状态,但它却在MSL时间内崩溃并重启,而且重启后使用崩溃前处于2MSL状态的端口号建立了新的连接,此时主机崩溃前连接的延迟TCP段就会被当前新的连接误用。为避免这种情况发生,RFC793规定在重启后的MSL时间内不应该建立新的连接,这称为quiet time。
一般来说,当一个到达的TCP段对于某个指定连接(referenced connection)不正确时,就需要发出一个重置段(reset segment)。
发出重置段的一个通常情况是:有连接请求到达,但却没有进程正在目标端口监听。比如telnet远程主机时指定一个不在使用的端口号,远程主机将发回一个重置段。看课本上列出的两个包:
0.0 bsdi.1087 > svr4.20000: S 297416193:297416193(0) win 4096 [tos 0x10]
0.003771 (0.0038) svr4.20000 > bsdi.1087: R 0:0(0) ack 297416194 win 0
由于svr4收到的TCP段没有打开ACK,因此重置段的顺序号是0。尽管收到的TCP段不带实际数据,但由于SYN位在逻辑上占用了顺序号空间的一个字节,所以本例中重置段的应答号是ISN+数据长度(为0)+1,即297416194。
TCP连接的正常终止的情况:一端在所有排队数据发出后才发送一个FIN来终止连接,这也叫做有序释放(orderly release)。但有的时候可能用一个RST代替FIN来异常终止(abort)某个连接,有时也称之为异常释放(abortive release)。
异常释放带给了应用程序两个特征:1)任何在排队的数据都被丢弃(throw away),并立即发出重置段;2)重置段的接受者能够区分对方是异常,而非正常关闭。应用程序使用的API必须提供产生异常而非正常关闭的方法。示例见P247-248。
 
TCP连接的半打开(half-open)状态:一端已经关闭或者异常终止,却没有把这些通知给另一端。任何一端的主机崩溃(crash)都可能产生半打开状态。只要不打算在半打开的TCP连接上传输数据,仍处于连接状态的那一端就不会去检查另一端已经崩溃。
一种通常情况是连接的客户端掉电(power off),而服务器却不知道这个客户端已经消失。当客户端重启时将新建与服务器连接,这样就导致了服务器上很多的半打开TCP连接。
实践示例见P249。
两端的应用程序同时向对方执行主动打开的情况是可能的,尽管发生的概率很小,这称为同时打开(simultaneous open)。
TCP对同时打开进行了针对性的设计,遵守的原则是同时打开只建立一个连接,而非两个。
图:同时打开时的TCP段交换

同样地,连接两端同时执行主动关闭的情况称为同时关闭(simultaneous close)。同时关闭时TCP段交换的图见下:
TCP选项和TCP服务器设计(略)。
_xyz