答案不是很学术,但至少根据 RFC 4960 中的规范,SCTP 似乎能够规避线头阻塞。相关声明似乎在第 7.1 节中。
注意:TCP 保证在单个 TCP 会话中按顺序将数据传送到其上层协议。这意味着,当 TCP 注意到接收到的序列号中有一个间隙时,它会等到该间隙被填满,然后才会传递接收到的序列号高于丢失数据的数据。另一方面,如果流序列号对于特定流是按顺序排列的(即丢失的 DATA 块是针对不同的流),或者如果指示未订购的交货。虽然这不会影响 cwnd,但它可能会影响 rwnd 计算。
一个难题是“按特定流的顺序排列”意味着什么?有一些关于延迟交付到上层的规定,直到包裹被重新排序(参见下面的第 6.6 节),但重新排序似乎并不以填补关联级别的空白为条件。还要注意第 6.2 节中提到的关于 ACK 和交付到 ULP(上层协议)之间的复杂区别。
RFC的其他规定是否间接导致HOL的发生,在现实生活中的实现和情况下是否有效——这些问题值得进一步研究。
以下是我在 RFC 中遇到的一些摘录,它们可能是相关的。
RFC 4960,第 6.2 节关于接收数据块的确认
当接收方的通告窗口为 0 时,接收方必须丢弃任何 TSN 大于目前接收到的最大 TSN 的新传入 DATA 块。如果新传入的 DATA 块持有的 TSN 值小于迄今为止接收到的最大 TSN,则接收者应该丢弃为重新排序而持有的最大 TSN 并接受新传入的 DATA 块。在任何一种情况下,如果这样的 DATA 块被丢弃,接收者必须立即发送回一个 SACK,当前接收窗口仅显示到目前为止接收和接受的 DATA 块。丢弃的 DATA 块不能包含在 SACK 中,因为它们不被接受。
在某些情况下,数据接收器可能需要丢弃它已接收但尚未从其接收缓冲区释放(即,传递到 ULP)的 DATA 块。这些 DATA 块可能已在 Gap Ack 块中被确认。例如,当数据接收器用完接收缓冲区空间时,它可能在其接收缓冲区中保存数据,同时重新组装来自其对等方的分段用户消息。即使它已在 Gap Ack 块中确认它们,它也可能会丢弃这些 DATA 块。如果数据接收者丢弃了 DATA 块,它绝不能将它们包含在后续 SACK 的 Gap Ack 块中,直到通过重传再次接收到它们。此外,端点在计算其 a_rwnd 时应考虑丢弃的数据。
强调发送方如何接收对最终未传递到 ULP(上层协议)的块的确认的情况。注意这适用于 TSN 高于累积 TSN(即来自 Gap Ack 块)的块。这与 SACK 顺序的不可靠性一起代表了第 7.1 节中规定的充分理由(见下文)。
RFC 4960,第 6.6 节有序和无序交付
在流中,端点必须根据其流序列号的顺序将接收到的 U 标志设置为 0 的 DATA 块传送到上层。如果 DATA 块按其流序列号的顺序到达,端点必须保持接收到的 DATA 块从交付到 ULP 直到它们被重新排序。
这是本节中关于流内有序交付的唯一规定;看起来,重新排序并不依赖于填充 ACK-ed 块中的空白。
RFC 4960,第 7.1 节 SCTP 与 TCP 拥塞控制的区别
SCTP SACK 中的 Gap Ack 块与 TCP SACK 具有相同的语义。TCP 仅将 SACK 中携带的信息视为建议信息。SCTP 将 SACK 块中的 Gap Ack 块中携带的信息视为建议。在 SCTP 中,任何已经被 SACK 确认的 DATA 块,包括乱序到达接收端的 DATA,直到 Cumulative TSN Ack Point 通过 DATA 块的 TSN(即 DATA 块已经由 SACK 中的 Cumulative TSN Ack 字段确认)。
这是从发送端点的角度陈述的,并且由于上面第 6.6 节中强调的原因是准确的。
注意:TCP 保证在单个 TCP 会话中按顺序将数据传送到其上层协议。这意味着,当 TCP 注意到接收到的序列号中有一个间隙时,它会等到该间隙被填满,然后才会传递接收到的序列号高于丢失数据的数据。另一方面,如果流序列号对于特定流是按顺序排列的(即丢失的 DATA 块是针对不同的流),或者如果指示未订购的交货。虽然这不会影响 cwnd,但它可能会影响 rwnd 计算。
这似乎是您感兴趣的核心答案。
为了支持这个论点,这里和这里公开的 SCTP SACK 块的格式。