TCP/IP学习笔记(4)

TCP

TCP提供一种面向连接的、可靠的字节流服务
面向连接意味着两个使用tcp的应用在彼此交换数据之前必须先建立一个TCP连接。
在一个TCP连接中,仅有两房进行彼此通信。广播和组播不能用于TCP。

 

TCP通过下列方式来提供可靠性:

应用程序被分割成TCP认为最适合发送的数据块

当TCP发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段。

当TCP收到发自TCP连接另一端的数据,它将发送一个确认。这个确认不是立即发送,通常将推迟几分之一秒。

TCP将保持它首部和数据的校验和。

既然TCP报文段作为IP数据报来传输,而IP数据报的到达可能会失序,因此TCP报文段的到达也可能会失序。如果必要,TCP将对收到的数据进行重新排序,将收到的数据以正确的顺序交给应用层。

既然IP数据报会发生重复,TCP的接收端必须丢弃重复的数据。

TCP还能提供流量控制。TCP连接的每一方都有固定大小的缓冲空间。TCP的接收端只允许另一端发送接收端缓冲区suo

 

TCP的字节流

两个应用程序通过TCP连接交换8bit字节构成的字节流。TCP不在字节流中插入记录标识符。我们将这称为字节流服务。如果一方的应用程序先传10字节,又传20字节,再传50字节,连接的另一方将无法了解发方每次发送了多少字节。收方可以分4次接受这80个字节,每次接收20字节。一端将字节流放到TCP连接上,同样的字节流将出现在TCP连接的另一端。

另外,TCP对字节流的内容不作任何解释。TCP不知道传输的数据字节流是二进制数据,还是ASCII字符、EBCDIC字符或者其他类型数据。对字节流的解释由TCP连接双方的应用层解释。

 

TCP首部

 

每个TCP段都包含源端和目的端的端口号,用于寻找发端和收端应用程序。这两个值加上IP首部中的源端IP地址和目的端IP地址唯一确定一个TCP连接。

一个IP地址和一个端口号也称为一个插口(socket)插口对(socketpair)(包含客户IP地址、客户端口号、服务器IP地址和服务器端口号的四元组)可唯一确定互联网络中每个TCP连接的双方。

序号用来标识从TCP发送端向TCP收端发送的数据字节流,它表示在这个报文段中的第一个数据字节。如果将字节流看做在两个应用程序间的单向流动,则TCP用序号对每个字节进行计数。序号是32bit的无符号数,序号到达232-1后又从0开始。SYN标志消耗了一个序号。

确认序号应当是上次已成功收到数据字节序号加1.只有ACK标志位1时确认序号字段才有效。

发送ACK无需任何代价,因为32bit的确认序号字段和ACK标志一样,总是TCP首部的一部分,因此,我们看到一旦一个连接建立起来,这个字段总是被设置,ACK标志也总是被设置为1.

TCP为应用层提供全双工服务。这以为数据能在两个方向上独立地进行传输。因此,连接的每一端必须保持每个方向上的传输数据序号。

TCP可以表述为一个没有选择确认否认的滑动窗口协议。我们说TCP缺少选择确认是因为TCP首部中的确认序号表示发方已成功收到字节,但还不包含确认序号所指的字节。当前还无法对数据流中选定的部分进行确认。例如,如果1~1024字节已经成功收到,下一报文段中包含序号从2049~3072的字节,收端并不能确认这个新的报文段。它所能做的就是发回一个确认序号为1025的ACK。它也无法对一个报文段进行否认。例如,如果收到包含1025~2048字节的报文段,但它的检验和错,TCP接收端所能做的就是发回一个确认序号为1025的ACK。在

首部长度给出首部中32bit字的数目。需要这个值是因为任选字段的长度是可变的。这个字段占4bit,因此TCP最多有60字节的首部。然而,没有任选字段,正常的长度是20字节

在TCP首部中有6个标志比特。他们中的多个可同时被设置为1。

TCP的流量控制由连接的每一端通过声明的窗口大小来提供。窗口大小为字节数,起始于确认序号字段指明的值,这个值是接收端正期望接受的字节。窗口大小事一个16bit字段,因而窗口大小最大为65535字节。

检验和覆盖了整个的TCP报文段:TCP首部和TCP数据。这是一个强制性的字段,一定是由发端计算和存储,并由收端进行验证。TCP检验和的计算和UDP检验和的计算相似,有伪首部。

只有当URG标志置1时紧急指针才有效。紧急指针是一个正的偏移量,和序号字段中的值相加表示紧急数据最后一个字节的序号。TCP的紧急方式是发送端向另一端发送紧急数据的一种方式。

最常见的可选字段是最长报文大小,又称为MSS。每个连接方通常都在通信的第一个报文段中指明这个选项。它指明本端所能接受的最大长度的报文段。

TCP报文段中的数据部分是可选的。在一个连接建立和一个连接终止时,双方交换的报文段仅有TCP首部。如果一方没有数据要发送,也使用没有任何数据的首部来确认收到的数据。在处理超时的许多情况中,也会发送不带任何数据的报文段。

建立一个连接需要三次握手,而终止一个连接要经过4次握手。这由TCP的瓣关闭造成的。既然一个TCP连接是全双工,因此每个方向必须单独地进行关闭。这原则就是当一方完成它的数据发送人物后就能发送一个FIN来终止这个方向连接。当一端收到一个FIN,它必须通知应用层另一端终止了哪个方向的数据传送。发送FIN通常是应用层进行关闭的结果。

收到一个FIN只以为着在这一方向上没有数据流动。一个TCP连接在收到一个FIN后仍能发送数据。而这对利用瓣关闭的应用来说时可能的,尽管在实际应用中只有很少的TCP应用程序这样做。

首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。通常一方完成主动关闭而另一方完成被动关闭。发送FIN将导致应用程序关闭他们的连接,这些FIN的ACK是由TCP软件自动产生的。

 

如果一方不接受另一方的MSS值,则MSS就定为默认值536字节。

一般来说,如果没有分段繁盛,MSS还是越大越好。

 

2MSL等待状态

TIME_WAIT状态也称为2MSL等待状态。每个具体TCP实现必须选择一个报文段最大生存时间MSL。它是任何报文段被对其前在网络内的最长时间。

RFC793支出MSL为2分钟。然而,现实中的常用值是30秒,1分钟,或2分钟。

对一个具体实现所给定的MSL值,处理的原则是:当TCP执行一个主动关闭,并发回最后一个ACK,该连接必须在TIME_WAIT状态停留的时间为2倍的MSL。这样可让TCP再次发送最后的ACK以防这个ACK丢失(另一端超时并重发最后的FIN)。

这种2MSL等待的另一个结果是这个TCP连接在2MSL等待期间,定义这个连接的插口(客户的IP地址和端口号,服务器的IP地址和端口号)不能再被使用。这个连接只能在2MSL结束后才能再被使用。

遗憾的是,大多数TCP时间强加了更为严格的限制。在2MSL等待期间,插口中使用的本地端口在默认情况下不能再被使用。

在连接处于2MSL等待时,任何迟到的报文段将被丢弃。因为处于2MSL等待的、由该插口对定义的连接在这段时间内不能被再用,因此当腰建立一个有效的连接时,来自该连接的一个较早替身的迟到报文段作为新连接的一部分不可能不被曲解。

平静时间

对于来自某个连接的较早替身的迟到报文段,2MSL等待可防止将它解释称使用相同插口对的新连接的一部分。但这只有在处于2MSL等待连接中的主机处于正常工作状态时才有效。

如果使用处于2MSL等待端口的主机出现故障,它会在MSL秒内重新启动,并立即使用故障前仍处于2MSL的插口对来建立一个新连接么?如果是这样,在故障前从这个连接发出而迟到的报文段会被错误地当做属于重启后新连接的报文段。无论如何选择重启后新连接的初始序号,都会发生这种情况。

为了防止这种情况,RFC793支出TCP在重启动后的MSL秒内不能建立任何连接。这就称为平静时间。

只有极少的实现版遵守这一原则,因为大多数主机重启动的时间都比MSL秒要长。

FIN_WAIT_2状态

在FIN_WAIT_2状态我们已经发出了FIN,并且另一端也已对它进行确认。除非我们在实行半关闭,否则将等待另一端的应用层意识到它收到一个文件结束符说明,并向我们发一个FIN来关闭另一方向的连接。只有当另一端的进程完成这个关闭,我们这段才会从FIN_WAIT_2状态进入TIME_WAIT状态。

这意味着我们这端可能永远保持这个状态。另一端也将处于CLOSE_WAIT状态,并一直保持这个状态知道应用层决定进行关闭。

复位报文段

RST是用于“复位”的。一般来说,无论何时一个报文段发往基准的连接出现错误,TCP都会发出一个复位报文段(“基准连接”是指由目的IP地址和目的端口号以及源IP地址和源端口号指明的连接。这就是为什么RFC793称之为插口)

异常终止一个连接

终止一个连接的正常方式是一方发送FIN。有时这也成为有序释放。

有可能发送一个复位报文段而不是FIN来中途释放一个连接。有时称这为异常释放。

异常终止一个连接对应用程序来说有两个有点:(1)丢弃任何待发数据并立即发送复位报文段;(2)RST的接收方会区分另一端执行的是异常关闭还是正常关闭。应用程序使用的API必须提供产生异常关闭而不是正常关闭的手段。

TCP选项

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

<mss 512, nop, wscale 0, nop, nop, timestamp 146647 0>

MSS选项设置为512,后面是NOP,接着是窗口扩大选项。第一个NOP用来将窗口扩大厢填充为4字节的便捷。同样,10字节的时间戳选项放在两个NOP后,占12字节,同事使两个4字节的时间戳满足4字节边界。

TCP的交互数据流

如果按照分组数量计算,约有一半的TCP报文段包含成块数据(如FTP、电子邮件和Usenet新闻),另一半则包含交互数据(如Telnet和Rlogin)‘

如果按字节计算,则成块数据与交互数据的比例约90%和10%

TCP需要同时处理这两类数据,但使用的处理算法则有所不同。

Nagle算法(低速链路有用)

该算法要求一个TCP连接上最多只能有一个未被确认的为完成的小分组,在该分组的确认到达之前不能发送其他的小分组。相反,TCP收集这些少量的分组,并在确认到来时以一个分组的方式发出去。该算法的优越之处在于它是自适应的:确认到达得越快,数据也就发送得越快。而在希望减少微小分组数目的低速广域网上,则会发送更少的分组。

注意到从左到右待发数据的长度是不同的,分别是:1、1、2、1、2、2、3、1和3个字节。这是因为客户只有收到前一个数据的确认后才发送已经收集的数据。通过使用Nagle算法,为发送16个字节的数据客户只需要使用9个报文段,而不再是16个。

TCP的成块数据流

TFTP使用了停止等待协议。数据发送方在发送下一个数据块之前需要等待接收对已发送数据的确认。该协议允许发送方在停止并等待确认前可以连续发送多个分组。由于发送方不必每发一个分组就停下来等待确认,因此该协议可以加速数据的传输。

慢启动

该算法通过观察到新分组进入网络的速率应该与另一端返回确认的速率相同

拥塞窗口,记为cwnd。当与另一个网络的主机建立TCP连接时,拥塞窗口被初始化为1个报文段。每收到一个ACK,拥塞窗口就增加一个报文段。发送方取拥塞窗口与通告窗口中的最小值作为发送上限。拥塞窗口是发送方使用的流量控制,而通告窗口则是接收方使用的流量控制。

发送方开始时发送一个报文段,然后等待ACK。当收到该ACK时,拥塞窗口从1增加为2,即可以发送两个报文段。当收到这两个报文段的ACK时,拥塞窗口就增加为4,。这是一种指数增加的关系。

在某些点上可能达到了互联网的容量,于是中间路由器开始丢弃分组。这就通知发送方它的拥塞窗口开得过大

发送一个分组的时间

低速链路:主要是发送时延起主要作用

高速链路:主要是传播时延占主要时延

TCP的超时和重传

4个定时器:1)重传定时器使用于当希望收到另一端的确认;2)坚持定时器使窗口大小信息保持不断流动,即使另一端关闭了其接受窗口;3)保活定时器可检测到一个空闲连接的另一端何时崩溃或重启;4)2MSL定时器测量一个连接处于TIME_WAIT状态的时间。

RTT计算:有一些算法。任何时候仅测量一次RTT。

拥塞避免

拥塞避免算法是一种处理丢失分组的方法

该算法假定由于分组收到损坏引起的丢失是非常少的,因此分组丢失就意味着在源主机和目的主机之间的某处网络上发生了拥塞。

有两种分组丢失的指示:发生超时和接收到重复的确认。

如果使用超时作为拥塞指示,则需要使用一个好的RTT算法

拥塞避免算法和慢启动算法是两个目的不同、独立的算法。但是当拥塞发生时,我们希望降低分组进入网络的传输速率,于是可以调用慢启动来做到这一点。在实际中这两个算法通常在一起实现。

快速重传和快速恢复算法

快速重传算法:如果一连串收到3个或3个意义上的重复ACK,就非常可能是一个报文段丢失了。于是我们就重传丢失的数据报文段,而无需等待超时定时器溢出。

快速恢复算法:快速重传后执行的不是慢启动算法而是拥塞避免算法。

TCP的重新分组、TCP的坚持定时器、糊涂窗口综合征、TCP的保活定时器

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值