让我们回顾一下互联网。
互联网是一个分组交换网络,其中第 3 层,即 IP,是基于分组的尽力而为的交付服务。Internet 中没有第 3 层确认之类的东西。所以,路由器不承认。如果发生故障,可以将 ICMP 消息发送给发送方,但它们不会影响相关数据包的处理方式。
在 Internet 中,如果需要,可靠的数据包传递通常由传输层(第 4 层)完成。传输层(至少在理论上)仅在两个端点上工作,并且所有传输层的 ACK 和重传仅发生在发送方和接收方,而不是介于两者之间的系统上。如果您想知道为什么它会这样工作,您可以阅读论文End-to-End Argument in System Design 。
现在,数据链路层。尽力而为的分组服务可以在任何数据链路层之上工作,因此数据链路层可以是可靠的或不可靠的/尽力而为的。根据经验,如果数据包错误(导致数据包无法正确传递的任何事件)过于频繁,则拥有可靠的第 2 层是有意义的。这通常转化为 - 有线第 2 层是尽力而为,而无线第 2 层是可靠的。还要注意,无线第 2 层通常只出现在边缘,即在端点和它们的第一个路由器之间。如果第 2 层可靠,则在两个第 2 层端点之间发生确认和重传。请注意,第 2 层有自己的确认,它们独立于传输层的确认。所以,如果 R3 和接收器之间的数据链路层是可靠的,然后 R3 的数据链路层将不得不存储数据包,直到它收到一个 ACK 并在必要时重新传输它几次。R2 和 R3 之间也会发生同样的情况,但除非我们在无线网状网络中,否则数据链路层不太可能可靠。
现在托管问题、校验和等。
问题:3 现在数据到达接收端的 DLL。我的问题是数据通过 DLL 传输到 TL 数据丢失是可能的吗?
是的。接收器的每一层都有处理队列,其中空间有限。如果数据包没有空间,它可能会被丢弃。
例子:
在可靠的第 2 层上,您可能会采用某种形式的流量控制。在不可靠的第 2 层,如果网卡的队列已满并且主机系统没有及时拾取数据包,则网卡可能会丢弃数据包。
我遇到了一种情况,即 linux TCP 接收器丢弃了数据包,尽管在接收器窗口中有广告空间。它需要太多解释并且超出了这里的范围,但重要的是它不违反规范。
如果 DLL 没有得到接收方传输层的确认,那么数据会从 DLL 重新发送到接收方的传输层,还是数据从发送方 DLL 或发送方传输层通过 TL 重新发送到接收方 DLL?
理论上,DLL 不会从传输层获取或处理确认。可靠的第 2 层将使用它自己的确认。来自传输层的确认被视为带有内容的抽象数据包。因此,缺少的 DLL 确认由 DLL peer 处理,在您的示例中为 R3。丢失的传输层确认由发送方的 TL 处理。
在实践中,事情并没有这么简单。有损失的网络上的 TCP 性能非常不理想(主要是由于与拥塞控制有关的原因)。这就是为什么无线通常是可靠的。此外,无线接入点很可能会采用某种优化来监控 TCP 流。我会说这种优化并不真正适合 OSI 模型。这也是性能优化。如果您关闭它,网络应该可以工作。
问题:4 如果接收端DLL中发生了重新排序,那么传输层也总是得到有序数据,传输层不需要排序吗?
不。同样,第 3 层是尽力而为,并且可以重新排序数据包。这意味着第 4 层应该准备好接收乱序数据包并将它们分类。无论第 2 层能保证什么,第 3 层都不会保证,传输层必须处理这个问题。
例子:
数据包可以通过不同的路线。如果路线改变,就会发生这种情况。如果其中一个路由器沿多条路径(例如,(等价)-多条路径)进行某种类型的负载平衡,也会发生这种情况。回想一下,在分组交换网络中,每个数据包的路由与前一个数据包发生的情况无关。
在实践中,同样,由于每个人都在使用 TCP,因此希望设计第 3 层和第 2 层以避免重新排序相同传输层流的数据包。路由器通常会进行负载平衡,以便同一流(由 ip 地址/端口/协议元组标识)的数据包在同一路径上路由。同样,这是一个影响性能的优化。如果不这样做,传输层应该是完全正常的。
另一个非常奇怪的例子是具有多核处理器的接收器,也就是现在几乎所有的端点。数据包由核心并行处理,两个不同核心处理的两个数据包可以以任意顺序到达接收方传输层。同样,通常网卡检查传输流并确保相同流的数据包由相同的核心处理,但我看到了没有发生这种情况的情况。