关于ARQ(自动重复请求)和重传
一个处理分组丢失的方法是重发分组直到它被正确接收。这需要一种方法来判断:1. 接收方是否已收到分组
2. 接收方接收到的分组是否与之前发送方发送的一样。
3. 接收方给发送方发信号以确定自己已经接收到一个分组,这种方法称为确认(acknowledgment),或ACK。
最基本的形式是发送方发送一个分组,然后等待一个ACK。当接收方接收到这个分组时,它发送对应的ACK。当发送方接收到这个ACK,它再发送另一个分组,这就是整个过程。
这里面有几个问题:1. 发送方对一个ACK应该等待多长时间?
2. 如果ACK丢了怎么办?
3. 如果分组被接收到了,但是里面有错怎么办?
第一、二个问题对应于TCP超时与重传。
第三个问题通过使用一个校验和的形式,当接收方接收到一个含有差错的分组时,它不发送ACK,最后发送方重发完整到达的无差错分组。
关于分组窗口和滑动窗口
如果发送方只注入一个分组到通信路径,然后停下来等待直到收到ACK,无疑这个网络的传输性能非常低。对于不会损害和丢失太多分组的网络来说,低吞吐量的原因是网络经常没有处于繁忙状态。但是当允许多个分组进入网络,就可以使它“更繁忙”,从而得到更高的吞吐量。
允许多个分组同时进入网络使事情变得复杂。现在发送方不仅要决定什么时间注入一个分组到网络中,还要考虑注入多少个。并且必须要指出在等待ACK时,怎样维持计时器,同时还必须要保存每个还没确认的分组的一个副本以防需要重传。接收方需要一个更复杂的ACK机制:可以区分哪些分组已经收到,哪些没有。接收方可能需要一个更复杂的缓存机制----允许维护次序杂乱(那些比预想要先到的分组更早到达的分组,因为丢包和次序重排的原因)的分组,除非简单的抛弃这些分组,而这样做是很没有效率的。还有其他一些没有这么明显的问题:
1. 如果接收方的接受速率比发送方的发送速率要慢怎么办?
2. 如果发送方简单地以很高的速率发送很多分组,接收方可能因处理或内存限制而丢失这些分组怎么办?
3. 中间的路由器也会有相同的问题,如果网络基础设施处理不了发送方和接收方想要使用的数据发送率怎么办?
为了解决所有这些问题,我们假设每个分组有一个序列号开始,定义一个分组窗口作为已被发送方注入但还没完成确认的分组的集合。我们把这个窗口中的分组数量称为窗口大小。术语窗口来自这样的想法:如果你想在一个通信对话中发送的所有分组排成长长的一行,但只通过一个小孔来观察它们,你就只能看到它们的一个子集----像通过一个窗口观看一样。发送方得窗口可画图描述为下图那样。
这个图显示了当前三个分组的窗口,整个窗口的大小是3。3号分组已经被发送和确认,所以由发送方保存的它的副本可以被释放。分组7在发送方已经准备好,但还没有被发送,因为它还没有进入窗口。现在如果我们想象数据开始从发送方流到接收方,ACK开始以相反的方向流动,发送方可能下一步就接收到一个分组4的ACK。当这发生时,窗口向右边滑动一个分组,意味着分组4的副本可以释放了,而分组7可以被发送了。窗口的这种滑动给这种类型的协议增加了一个名字,滑动窗口协议。
关于变量窗口:流量控制和拥塞控制
为了处理当接收方相对发送方太慢时产生的问题,在接收方跟不上时会强迫发送方慢下来,这称为流量控制。一般通过以下两种方式来进行操作:1.基于速率的流量控制,它是给发送方指定某个速率,同时确保数据永远不能超过这个速率发送。
这种类型的流量控制最适合流应用程序,可被用于组播和广播发现。
2.基于窗口的流量控制,是使用滑动窗口时最流行的方法。
这种方法里窗口大小不是固定的,而是允许随时间而变动。为了使用这种技术进行流量控制,必须有一种方法让接收方可以通知发送方使用多大的窗口。这一般称为窗口通告,或简单的称为窗口更新。发送方使用该值调整其窗口大小。
逻辑上讲,一个窗口更新与ACK是分离的,但实际上窗口更新和ACK是由同一个分组携带的,意味着发送方往往会在它的窗口滑动到右边的同时调整它的大小。
这种方法可以很好地保护接收方,但是对于中间网络,例如在发送方和接收方之间可能会有有限内存的路由器,它们与低速网络链路抗争着。当这种情况出现时,发送方的速率可能超过某个路由器的能力,从而导致丢包。这一种特殊的称为拥塞控制的流量控制形式来处理。
设置重传超时
基于重传的可靠协议的设计者要面对的一个最重要的性能问题是,要等多久才能判定一个分组已丢失并将它重发。即重传超时应该多大?直观上看,发送方在重发一个分组之前应等待的时间量大概是下面时间的总和:发送分组所用的时间,接收方处理它和发送一个ACK所用的时间,ACK返回到发送方所用的时间,以及发送方处理ACK所用的时间。不幸的是,这些事件都不是确切知道的,而且会随时而改变。
一般的策略是让协议实现尝试去估计,这称为往返时间估计。总的来说,选择一组RTT样本的样本均值作为真实的RTT是最有可能的。注意到这个平均值很自然的随着时间而改变(它不是静态的),因为通信穿过的网络的路径可能会改变。
TCP头部和封装
下图显示了TCP头部图
每个TCP头部包含了源和目的端口号。这两个值和IP头部中的源和目的IP地址一起唯一的标识了每个连接。
序列号字段标识了TCP端到TCP端的数据流的一个字节,该字节代表着包含该序列号的报文段的数据中的第一个字节。确认号字段包含的值是该确认号的发送方期待接收的下一个序列号,即被成功接收的数据字节的序列号加1。
头部长度字段给出了头部的长度,以32位字为单位。
CWR----拥塞窗口减(发送方降低它的发送速率)
ECE-----ECN回显(发送方接收到了一个更早的拥塞通告)
URG----紧急(紧急指针字段有效)
ACK-----确认(确认号字段有效-----建立连接后一般都是启用状态)
PSH-----推送
RST-----重置连接
SYN----用于初始化一个连接的同步序列号
FIN-----该报文段的发送方已经结束向对方发送数据
TCP的流量控制由每个端点使用窗口大小字段来通告一个窗口大小来完成。
TCP校验和字段覆盖了TCP的头部和数据以及头部中的一些字段,使用一个与UDP相类似的伪头部进行计算。
TCP提供了一种可靠的、面向连接、字节流、传输层服务,应用有HTTP、SSH / TLS、Telnet、FTP以及电子邮件SMTP。