avatar

目录
TCP流量控制总结

TCP流量控制总结

🧑‍💻 User

Close


Flow control: Controlling the Transmission Rate to Protect the Receiver buffer

The first case where we need transmission control is to protect the receiver buffer from overflowing. Recall that TCP uses a buffer at the receiver end to buffer packets that have not been transmitted to the application. The receiver might be involved with multiple processes and does not read the data instantly. This can cause the accumulation of a massive amount of data and overflow the receive buffer.

TCP provides a rate control mechanism, also known as flow control, that helps match the sender’s rate against the receiver’s rate of reading the data. In addition, the sender maintains a variable receive window rwnd. It provides the sender an idea of how much data the receiver can handle at the moment.

We will illustrate its working using an example. Consider two hosts, A and B, communicating with each other over a TCP connection. Host A wants to send a file to Host B. Host B allocates a receive buffer of size **RcvBuffer** to this connection. The receiving host maintains two variables:

  • LastByteRead: the number of the last bytes in the data stream read from the buffer by the application process in B
  • **LastByteRcvd**: the number of the last bytes in the data stream that has arrived from the network and has been placed in the receive buffer at B

Thus, to not overflow the buffer, TCP needs to make sure that

LastByteRcvd - LastByteRead <= RcvBuffer

The extra space that the receive buffer has is specified using a parameter termed as receive window.

rwnd = RcvBuffer - [LastByteRcvd - LastByteRead]

Receive window and the receive buffer

The receiver advertises the value rwnd in every segment/ACK it sends back to the sender.

The sender also keeps track of two variables, **LastByteSent** and **LastByteAcked**.

UnACKed Data Sent = LastByteSent - LastByteAcked

To not overflow the receiver’s buffer, the sender must ensure that the maximum number of unacknowledged bytes it sends is no more than the rwnd. Thus we need

LastByteSent – LastByteAcked <= rwnd

Caveat: However, there is one scenario where this scheme has a problem. Consider a scenario where the receiver had informed the sender that rwnd = 0, and thus the sender stops sending data. Also, assume that B has nothing to send to A. Now, as the application processes the data at the receiver, the receiver buffer is cleared. Still, the sender may never know that new buffer space is available and will be blocked from sending data even when the receiver buffer is empty.

TCP resolves this problem by making the sender continue sending segments of size 1 byte even after rwnd = 0. When the receiver acknowledges these segments, it will specify the rwnd value, and the sender will know as soon as the receiver has some room in the buffer.


References

Kurose-Ross, Edition 6, Section 3.5.5


🤖 Assistant

费曼学习法自检 Checklist:TCP 流量控制 (Flow Control)


📋 自检清单 (Checklist)

第一层:核心概念理解

  • [ ] 1. 我能用一句话解释流量控制 (Flow Control) 的目的是什么吗?
  • [ ] 2. 我能说清楚接收窗口 (Receive Window, rwnd) 是什么吗?
  • [ ] 3. 我能解释为什么需要保护接收缓冲区 (Receive Buffer) 吗?

第二层:关键变量理解

  • [ ] 4. 我能说出接收方 (Receiver) 维护的两个变量是什么,分别代表什么含义吗?

    • LastByteRead
    • LastByteRcvd
  • [ ] 5. 我能说出发送方 (Sender) 维护的两个变量是什么,分别代表什么含义吗?

    • LastByteSent
    • LastByteAcked

第三层:公式与约束条件

  • [ ] 6. 我能写出并解释防止缓冲区溢出的约束条件吗?
  • [ ] 7. 我能写出 rwnd 的计算公式吗?
  • [ ] 8. 我能写出发送方必须遵守的发送约束吗?

第四层:机制运作流程

  • [ ] 9. 我能描述 rwnd 是如何在发送方和接收方之间传递的吗?
  • [ ] 10. 我能画出或描述接收缓冲区的示意图吗?

第五层:边界情况与解决方案

  • [ ] 11. 我能解释当 rwnd = 0 时会出现什么问题吗?
  • [ ] 12. 我能说明 TCP 是如何解决 rwnd = 0 死锁问题的吗?

第六层:能否教给别人

  • [ ] 13. 我能用自己的话,向一个不懂网络的朋友解释整个流量控制机制吗?
  • [ ] 14. 我能举一个生活中的类比来解释流量控制吗?

✅ 参考答案


问题 1:我能用一句话解释流量控制 (Flow Control) 的目的是什么吗?

答案: 流量控制的目的是让发送方的发送速率匹配接收方的处理速率,防止接收方的缓冲区溢出 (overflow)。


问题 2:我能说清楚接收窗口 (Receive Window, rwnd) 是什么吗?

答案: rwnd 是接收方告诉发送方的一个值,表示接收缓冲区当前还有多少剩余空间可以接收新数据。


问题 3:我能解释为什么需要保护接收缓冲区 (Receive Buffer) 吗?

答案: 因为接收方可能同时处理多个进程,不能立即读取数据。如果发送方发送太快,数据会在缓冲区堆积,最终导致缓冲区溢出,新到达的数据会丢失。


问题 4:接收方维护的两个变量是什么?

变量 含义
LastByteRead 应用程序从缓冲区已读取的最后一个字节的编号
LastByteRcvd 从网络已接收并放入缓冲区的最后一个字节的编号

问题 5:发送方维护的两个变量是什么?

变量 含义
LastByteSent 发送方已发送的最后一个字节的编号
LastByteAcked 发送方已收到确认 (ACK) 的最后一个字节的编号

问题 6:防止缓冲区溢出的约束条件是什么?

Code
1
LastByteRcvd - LastByteRead ≤ RcvBuffer

解释: 已接收但未被读取的数据量,不能超过缓冲区总大小。


问题 7:rwnd 的计算公式是什么?

Code
1
rwnd = RcvBuffer - (LastByteRcvd - LastByteRead)

解释: 接收窗口 = 缓冲区总大小 - 已占用的空间


问题 8:发送方必须遵守的发送约束是什么?

Code
1
LastByteSent - LastByteAcked ≤ rwnd

解释: 发送方未被确认的数据量 (UnACKed Data) 不能超过接收方通告的 rwnd 值。


问题 9:rwnd 是如何传递的?

答案: 接收方在每个发送回去的 ACK 段 (segment) 中携带当前的 rwnd 值,告知发送方。


问题 10:接收缓冲区示意图

Code
1
2
3
4
5
|<-------- RcvBuffer -------->|
| 已读取 | 已接收未读取 | 空闲空间 |
↑ ↑
LastByteRead LastByteRcvd
|<-- rwnd -->|

问题 11:当 Rwnd = 0 时会出现什么问题?

答案:

  • 接收方通知发送方 rwnd = 0,发送方停止发送
  • 如果接收方之后没有数据要发给发送方,发送方就永远不知道缓冲区已经清空
  • 造成死锁 (deadlock):发送方一直等待,接收方缓冲区已空却无法通知

问题 12:TCP 如何解决 Rwnd = 0 的死锁问题?

答案: TCP 让发送方在 rwnd = 0 后,持续发送 1 字节的探测段 (probe segment)。接收方收到后会回复 ACK,ACK 中会携带最新的 rwnd 值。一旦缓冲区有空间,发送方就能知道并恢复发送。


问题 13 & 14:生活类比

类比: 想象你在给朋友倒水 (发送数据),朋友的杯子 (接收缓冲区) 容量有限。朋友会告诉你”还能倒多少” (rwnd)。如果杯子满了 (rwnd=0),你停止倒水。但你会时不时问一句”能倒了吗?” (1字节探测),朋友喝一口后说”可以了” (新的rwnd),你就继续倒。


🎯 费曼检验标准:如果你能用以上类比向一个小学生解释清楚,说明你真正理解了!


评论