在 TCP Tahoe 中找到最终的拥塞窗口大小
给定初始拥塞窗口大小cwnd 、阈值ssthresh 、连接时间rtt和数组arr ,其中 arr[i] 表示检测到丢包的时间。任务是在发送方遇到所有丢包时找到最终的拥塞窗口大小。
The TCP Tahoe follows below conditions:
- The initial value of cwnd is 10.
- Before reaching ssthresh, double cwnd per unit of time. By doubling the value, cwnd can’t cross ssthresh value, it can almost go up to ssthresh value.
- After reaching ssthresh, increase cwnd by 1 per unit of time.
- When there is packet loss, reduce the ssthresh to half of cwnd value (50%), reset cwnd to initial value of 10 and no other updation happens.
- The connection will be active until rtt unit of time.
例子:
Input arr[] = {16, 25}, ssthresh = 320, rtt = 28
Output: 80
Explanation:
Time = 0: cwnd = 10
Time = 1: cwnd = 20
Time = 2, 3, 4, 5: cwnd = 40, 80, 160, 320
cwnd=ssthresh at time=5, so now onwards cwnd increases by 1 per unit of time.
Time = 6-15: cwnd = 321-330
Time = 16: packet loss is detected, so ssthresh will become half of current cwnd value.
ssthresh = 330/2=165, cwnd = 10 (reseted), Note: cwnd is not increased by 1 or doubled in this case.
Time = 17, cwnd = 20
Time = 18, cwnd = 40
Time = 19, cwnd = 80
Time = 20, cwnd = 160
Time = 21, cwnd = 165 {cwnd can’t get doubled because 320>165, it will cross the ssthresh. It can go max upto ssthresh}
Time = 22, cwnd = 166, so now onwards cwnd increases by 1 per unit of time.
Time = 23, cwnd = 167
Time = 24, cwnd = 168,
Time = 25: packet loss is detected, so ssthresh will become half of current cwnd value,
ssthresh = 168/2=84, cwnd=10 (reseted)
Time = 26: cwnd = 20
Time = 27, cwnd = 40
Time = 28, cwnd = 80
Final cwnd is = 80
Input arr[] = {12, 20, 31, 45}, ssthresh = 300, rtt = 50
Output: The final cwnd value is= 29
Explanation:
Time = 0: cwnd = 10
Time = 1: cwnd = 20
Time = 2, 3, 4: cwnd = 40, 80, 160
Time = 5: cwnd = 300 {cwnd can’t get doubled because 320>300, it will cross the ssthresh. It can go max upto ssthresh}
Time = 6-11: cwnd = 301-306
Time = 12: cwnd = 10 (reseted), and ssthresh = 306/2=153 {Packet loss}
Time = 13: cwnd = 20
Time = 14: cwnd = 40
Time = 15: cwnd = 80
Time = 16: cwnd = 153, {cwnd can’t get doubled because 160>153, it will cross the ssthresh. It can go max upto ssthresh}
Time = 17: cwnd = 154
Time = 18: cwnd = 155
Time = 19: cwnd = 156
Time = 20: cwnd = 10 (reseted), ssthresh = 156/2 = 78 {Packet loss}
Time = 21: cwnd = 20
Time = 22: cwnd = 20
Time = 23: cwnd = 40
Time = 24: cwnd = 78, {cwnd can’t get doubled because 80>78, it will cross the ssthresh. It can go max upto ssthresh}
Time = 25-30: cwnd = (78+1=79) – (78+6=84)
Time = 31: cwnd = 10 (reseted), ssthresh = 84/2 = 42 {Packet loss}
Time = 32: cwnd = 20
Time = 33, cwnd = 40
Time = 34, cwnd = 42, {cwnd can’t get doubled because 80>42, it will cross the ssthresh. It can go max upto ssthresh}
Time = 35-44: cwnd = 43 – 52
Time = 45: cwnd = 10 (reseted), ssthresh = 52/2 = 26 {Packet loss}
Time = 46: cwnd = 20
Time = 47: cwnd = 26 {cwnd can’t get doubled because 40>26, it will cross the ssthresh. It can go max upto ssthresh}
Time = 48-50: cwnd = 27-29
The final cwnd value is= 29
方法:想法是牢记所有约束并编写代码以最小的时间和空间复杂度运行。按照以下步骤操作:
- 当连接处于活动状态时,遍历所有时间单位。
- 将下一个丢包时间存储在可变超时中
- 检查当前时间是否等于超时。如果是,则减少ssthresh = cwnd/2并将cwnd 重置为 10 。
- 如果 cwnd 小于ssthresh ,则将cwnd值加倍。
- 如果cwnd的两倍大于ssthresh ,则设置cwnd=ssthresh。
- 如果cwnd大于ssthresh ,则每次将cwnd增加 1。
- 循环终止后返回最终的cwnd值。
下面是上述方法的实现。
C++
// C++ code to find the final size
// of congestion window in TCP TAHOE
#include
using namespace std;
// TCP Tahoe Utility function
int tcpTahoeCongestionWindow(
int initcwnd, int cwnd,
int ssthresh, int rtt,
vector time)
{
int ind = 0, timeout = time[ind];
for (int t = 1; t <= rtt; t++) {
// Packet loss occurs.
// Reduce ssthresh to half of
// current cwnd value.
// Reset cwnd to 10
if (t == timeout) {
ssthresh = cwnd / 2;
cwnd = initcwnd;
timeout = time[++ind];
continue;
}
// Threshold is not reached.
// Keep doubling
if (cwnd < ssthresh)
cwnd = min(2 * cwnd,
ssthresh);
// Threshold is reached.
// Increase additively.
else
cwnd += 1;
}
// Return final cwnd value.
return cwnd;
}
// Driver code
int main()
{
int initcwnd = 10, cwnd = 10;
int ssthresh = 300;
int rtt = 50;
vector time{ 12, 20, 31, 45 };
// Function call
cwnd = tcpTahoeCongestionWindow(
initcwnd, cwnd,
ssthresh, rtt, time);
cout << cwnd;
return 0;
}
Javascript
Final congestion window size = 29
时间复杂度: O(N),N是连接活跃的时间。
辅助空间: O(1)