TCP/IP协议使用的运输层协议或者是对这些协议之一的改进,或者是他们的组合。
简单协议
简单协议时一个无连接协议,它既没有流量控制,也没有差错控制。我们假设接收方能够及时处理它收到的任何分组。换言之,接收方永远不会因为涌入的分组太多而处理不过来,下图是这个协议的概要。
发送方的运输层从应用那里得到一个报文,用他产生一个分组,然后发送这个分组。接收方的运输层从网络层哪里收到一个分组,从分组中提取出该报文,然后将该报文交付给应用层。发送方和接收方的运输层为它们各自的应用层提供传输服务。
FSM(Finite State Machine)
在发送方的应用层有报文要发送之前,发送方不可能发送分组。在分组到达之前,接收方也不可能向应用层交付报文。我们可以用两个FSM来表示这些要求。每个FSM只有一个状态,即准备好状态。发送方状态机一直保持在准备好状态,直至应用层的进程又一个请求到来。当这个事件发生后,发送方状态机将报文封装成一个分组,并把这个分组发送给接收方状态机。接收方状态机也总是保持在准备好状态,直至来自发送方状态机的分组到达。当这个事件发生后,接收方状态机把收到的分组解封后提取出该报文,并把它交付给应用层的响应进程。下图所示为这个简单协议的FSM。
简单协议时一个无连接协议,既没有流量控制,也没有差错控制。
下图所示为使用这个协议进行通信的一个例子。它非常简单。发送方一个接一个地发送分组,甚至根本不用考虑接收方。
停止等待协议
停止等待协议(Stop-and-Wait protocol),是面向连接的协议,它使用了流量控制和差错控制。发送方和接收方都使用了大小为1对的滑动窗口。发送方一次发送一个分组,然后再发送下一个分组之前要先等待一个确认。为了检测损坏的分组,我们需要在每个数据分组中增加一个检验和,并在分组到达接收方后检查它。如果检验和不正确,就说明分组损坏了,这个分组被悄无声息的丢弃掉。接收方的沉默对发送方来说就是一个信号,说明分组不是损坏了就是丢失了。发送方在每次发送一个分组时要启动一个计时器。如果在计时器到期之前确认到了,计时器就停止计时,发送方继续发送下一个分组(如果还有其他分组的话)。如果该计时器超时,那么发送方就假定分组丢失或者损坏了,因而重传前一个分组。这就意味着发送方需要保存分组的副本直至它的确认到达位置。下图所示为停止等待协议的概要图,请注意,在任何时候通信道中都只有一个分组和一个确认。
停止等待协议是一种面向连接的协议,它提供了流量控制和差错控制,流量控制通过迫使发送方等待确认来实现,差错控制通过丢弃损坏的分组并让发送方在计时器超时后重传来确认的分组实现。
序号
为了防止重复的分组,协议使用了序号和确认号。分组的首部要增加一个字段用来保存分组的序号。序号的范围是需要慎重考虑的。因为我们希望分组的长度最小化,所以我们寻求的是不会混淆通讯的最小范围。让我们来推算一下所需要的序号范围。假设我们使用x作为一个序号,那么此后只需要用到x+1就够了,没有必要使用x+2.为了说明这个问题,我们假设发送方发送了一个序号为x的分组,可能会发生以下三种情况:
1、分组完全好地抵达接收方。接收方发送一个确认。这个确认到达发送方,是发送方继续发送下一个序号为x+1的分组。
2、分组损坏或者从未抵接收方。发送方在超时后重传这个分组(序号为x),接收方返回一个确认。
3、分组安全完好地抵达接收方,接收方发送一个确认,但是这个确认损坏或丢失了。发送方在超时后重传这个分组(序号为x)。注意此时这个分组时重复的。接收方能够识别出这种重复,因为它希望接收的分组是x+1,单实际接收到的分组却是x。
我们看的出序号x和x+1都是必要的,因为接收方需要用他们却分情况1和情况3.但是分组没有必要使用序号x+2.在情况1中,分组可以再次使用序号x,因为分组x和x+1都已经被确认了,发送方和接收方也没有什么并不清楚的地方。在情况2和情况3中,新的分组是x+1,不是x+2,如果仅仅需要x和x+1,那么我们可以让x=0且x+1=1,也就是说该序号是0、1、0、1、0....。这被称为模2运算(通常记为mod 2)。
确认号
因为序号必须既适合数据分组,又适合确认,所以我们有一下的约定:确认号总是生命了接收方准备接受的下一个分组的序号。例如:如果分组0已经安全完好地抵达了。那么接收方就发送一个确认号为1的ACK(表示下一个希望接收分组1)。如果分组1完全完好地抵达了,那么接收方就发送一个确认号为0的ACK(表示下一个希望接收分组0)。在停止等待协议中,确认号总是声明了模2运算的下一个希望接收的分组序号。
发送方有一个控制变量,我们称之为S(sender),它指向发送窗口中唯一的空格,接收方也有一个控制变量,我们称之为R(receiver),它指向接收窗口中唯一的空格。
FSM
下图描绘了停止等待协议的FSM。因为这个协议时面向连接的,所以在交换数据分组前,连接的两端都应当处于建立的状态。我们在这里所描述的状态实际上都是包含在建立的状态中的子状态。
发送方 发送方在一开始时处于准备好状态,但是它可以在准备好和阻塞这两个状态之间变换。变量S的值初始化为0.
准备好状态 当发送方处于此状态是,它仅等待一个实践的发生。如果来自应用层的请求到达了,发送方就产生一个序号设为S的分组。这个分组的一个副本被保存起来,而这个分组被发送出去。发送方启动唯一的计时器,然后进入阻塞状态。
阻塞状态 当发送方处于此状态时,可能会发生的事件有三个:
1、如果一个无差错的ACK到达,且它的确认号指向下一个要发送分组,也就是说ackNo=(S+1)mod 2,那么计时器停止计时,窗口滑动使S=(S+1)mod2.最后发送方进入装备好状态。
2、如果一个损坏的ACK到达,或者虽无差错但ackNo不等于(S+1)mod2的ACK到达,这个ACK被丢弃。
3、如果计时器超时,发送方重新传哪个唯一待确认分组,并重启计时器。
接收方 接收方总是在准备好状态,变量R的初始值为0.有三个事件可能会发生:
1、如果一个seqNo=R的无差错分组到达,那么这个分组中的报文被交付给应用层。然后欢动窗口到R=(R+1)mod 2,最后发送一个ackNo=R的ACK。
2、如果一个seqNo不等于R的无差错分组到达,这个分组被丢弃,但是要发送ackNo=R的一个ACK。
3、如果一个损坏的分组到达,这个分组被丢弃。
下图所示为一个停止等待协议的例子。分组0被发送且确认。分组1丢失并在计时超时后重传。重传的分组1被确认且计时器停止计时。分组0被发送且被确认,但是这个确认丢失了。发送方不知道丢失的是分组还是确认,因此在计时器超时后重传分组0,重传的分组0被确认。
返回N协议
选择重传协议
双向协议:捎带
数据分组仅在一个方向流动,而确认从两一个方向传过来。但是在显示生活中数据分组通常是双向流动的:从客户到服务器,并且从服务器到客户端。这就意味着确认也是需要双向流动。一种被称为捎带(piggybacking)的技术可用于提高双向协议的效率。当分组A向B携带数据的同时也能够携带返回的确认,这些确认说明了从B发来的分组的到达情况。而当分组从B向A携带数据的同时也能够携带返回的确认,这些确认又说明了从A发出来的分组的到达情况。
下图所示为利用捎带实现双向GBN协议的概要图。客户和服务器各使用两个独立的窗口:发送窗口和接收窗口。