多路复用和多路分解
运输层的多路复用与多路分解,也就是将由 “网络层提供的主机到主机交付服务”
延伸到 “为运行在主机上的应用程序提供进程到进程的交付服务”。
前提:
在目的主机,运输层从紧邻其下的网络层接收报文段。
运输层负责将这些报文段中的数据交付给在主机上运行的适当应用程序进程。
套接字相当于从网络向进程传递数据和从进程向网络传递数据的门户
我们知道,一个主机上可能有多个套接字, 所以每个套接字都有唯一的标识符(源目端口号)。
标识符的格式取决于它是UDP还是TCP套接字。
多路分解
在接收端,运输层检查这些字段,标识出接收套接字,进而将报文段定向到该套接字。
将运输层报文段中的数据交付到正确的套接字的工作称为多路分解(demultiplexing)。
- UDP的多路分解:
UDP套接字是由一个二元组全面标识的,该二元组包含一个目的IP地址和一个目的端口号。因此,如果两个UDP报文段有不同的源IP地址 和/或源端口号,但具有相同的目的IP地址和目的端口号,那么这两个报文段将通过相同的目的套接字被定向到相同的目的进程。
- TCP的多路分解:
TCP套接字是由一个四元组(源1P地址, 源端口号,目的IP地址,目的端口号)来标识的。因此,当一个TCP报文段从网络到达 一台主机时,该主机使用全部4个值来将报文段定向(分解)到相应的套接字。特别与 UDP不同的是,两个具有不同源IP地址或源端口号的到达TCP报文段将被定向到两个不同的套接字,除非TCP报文段携带了初始创建连接的请求。
多路复用
在源主机从不同套接字中收集数据块,并为每个数据块封装上首部信息(这将在以后用于分解)从而生成报文段,
然后将报文段传递到网络层,所有这些工作称为多路复用(multiplexing)。
构造可靠数据传输协议需要什么?
①有没有发生比特差错(信道是否可信)?
我们需要四个方面来确定:
- 差错检测:反码校验和
- 携带序号发送(01互换发送)
- 接收方反馈(ACK+序号) :正确确认时,会收到预期内的序号;否定确认报文通常携带着未被正确接收的分组的序号
- 重传机制:当接收到非预期内的反馈时,进行重传
②有没有发生丢包?
- 定时器
- 发送报文时即开启定时器
等待接收方反馈(分为两种情况)
① 接收到并返回ACK包 --> 终止定时器,发包时重新计时<br /> ② 未收到响应包 --> 等待定时器超时,进行重传

ps:
但仅依靠上面这些还不能组成可靠的数据传输协议(数据传播太慢:因为它是个停等协议)
3.4.2流水线传输协议
由于停等协议的关系,我们采用流水线,这种增加序号的方式来提高链路带宽利用率。

解决流水线的差错恢复有两种基本方法是: 回退N步 (Go- Back- N, GBN)和 选择重传(Selective Repeat,SR)
回退N步
在回退N步(GBN)协议中 ,允许发送方发送多个分组(当有多个分组可用时)而 不需等待确认,
但它也受限于在流水线中未确认的分组数不能超过某个最大允许数N。

已被发送但还未被确认的分组的许可序号范围可以被 看成是一个在序号范围内长度为N的窗口。
随着协议的运行,该窗口在序号空间向前滑动。因此,被称为窗口长度(window size )
GBN协议也常被称为滑动窗口协议
GBN发送方必须响应三种类型的事件:
- 上层的调用。 当上层调用rdt_send()时,发送方首先检查发送窗口是否已满,即是 否有N个已发送但未被确认的分组。如果窗口未满,则产生一个分组并将其发送, 并相应地更新变量。如果窗口已满,发送方只需将数据返回给上层,隐式地指示上层该窗口已满。然后上层稍后重试。
- 收到一个ACK。在GBN协议中 ,对序号为几的分组的确认采取累积确认(cumulative acknowledgment)的方式,表明接收方已正确接收到序号为n的以前且包括n在内的所有分组。
- 超时事件。如果出现超时,发送方重传所有已发送但还未被确认过的分组。发送方仅使用一个定时器,它可被当作是最早的已发送但未被确认的分组所使用的定时器 。如果收到一个ACK,但仍有已发送但未被确认的分组,则定时被重新启 动。如果没有已发送但未被确认的分组,停止该定时器 。
GBN接收方的响应动作:
如果一个序号为n的分组被正确接收到,并且 按序(即上次交付给上层的数据是序号为n-1的分组),则接收方为分组n发送一个 ACK,并将该分组中的数据部分交付到上层。在所有其他情况下,接收方丢弃该分组,并为最近按序接收的分组重新发送ACK。
关于接收方和发送方的维护消耗:
发送方必须维护窗口的上下边界及 nextseqnum在该窗口中的位置
接收方需要维护的唯一信息就是下一个按序接收的分组的序号。

选择重传
选择重传(SR)协议通过让发送方仅重传那些它怀疑在接收方出错(即 丢失或受损)的分组,而避免了不必要的重传。
SR接收方将确认一个正确接收的分组而不管其是否按序。失序的分组将被缓存直到所有丢失分组(即序号更小的分组)皆被收到为止,这时才可以将一批分组按序交付给上层。

SR发送方的事件与动作
- 从上层收到数据。当从上层接收到数据后,SR发送方检査下一个可用于该分组的序号。如果序号位于发送方的窗口内,则将数据打包并发送;否则就像在GBN中一样,要么将数据缓存,要么将其返回给上层以便以后传输。
- 超时。定时器再次被用来防止丢失分组。然而,SR中每个分组拥有其自己的逻辑定时器. 所以超时发生后只发送该分组。
- 收到ACK。如果收到ACK,倘若该分组序号在窗口内,则SR发送方将那个被确认的分组标记为已接收。 如果该分组的序号等于send.base,则窗口基序号向前移动到具有最小序号的未确认分组处。如果窗口移动了并且有序号落在窗口内的未发送分组,则发送这些分组。
SR接收方的事件与动作
- 序号在[rcv_base. rcv_base +N - 1 ]内的分组被正确接收。在此情况下,收到的分组落在接收方的窗口内,一个选择ACK被回送给发送方。如果该分组以前没收到过,则缓存该分组。如果该分组的序号等于接收窗口的基序号的rcv_base 时,则该分组以及以前缓存的序号连续的分组交付给上层。 然后,接收窗口按向前移动分组的编号向上交付这些分组。
- 重新确认。序号在[rcv_base - N, rcv_base-1]内的分组被正确收到。在此情况下.必须产生一个ACK,即使该分组 是接收方以前已确认过的分组。( 如果接收方不确认该分组,则发送方窗口将永远不能向前滑动!)
- 其他情况。忽略该分组。

