哪个TCP窗口更新是最近的?

哪个TCP窗口更新是最近的?,tcp,Tcp,我在写一个TCP实现,做了所有有趣的慢速和快速重传的事情,一切都很好,所以我认为我完成了。但后来我回顾了我的数据包接收功能(几乎是400行代码的一半),并意识到我对基本流控制的理解是不完整的 假设我们有一个与“发送方”和“接收方”的TCP连接。假设“发送方”没有发送任何内容,而接收方正在暂停,然后取消暂停 因为“发送方”没有发送任何东西,“接收方”看不到任何应答。因此,“接收器”的两个窗口更新如下所示: 确认号=X,窗口=0 确认号=X,窗口=8K 由于两个数据包具有相同的确认号,并且它们可以在

我在写一个TCP实现,做了所有有趣的慢速和快速重传的事情,一切都很好,所以我认为我完成了。但后来我回顾了我的数据包接收功能(几乎是400行代码的一半),并意识到我对基本流控制的理解是不完整的

假设我们有一个与“发送方”和“接收方”的TCP连接。假设“发送方”没有发送任何内容,而接收方正在暂停,然后取消暂停

因为“发送方”没有发送任何东西,“接收方”看不到任何应答。因此,“接收器”的两个窗口更新如下所示:

  • 确认号=X,窗口=0
  • 确认号=X,窗口=8K
  • 由于两个数据包具有相同的确认号,并且它们可以在传输过程中重新排序,发送方如何知道哪个先到

    如果发送方不知道哪一个先到,那么在收到两个数据包之后,它如何知道是否允许发送

    一种猜测是,可能永远不允许窗口的上端点减小?一旦接收者分配了一个接收缓冲区并公布了它,它就永远不能取消公布它?在这种情况下,可以通过以下代码可靠地处理窗口更新(为简单起见,假设没有窗口比例):


    但从接收器的角度来看,这是可怕的:它大大增加了可靠支持10K连接所需的内存。协议肯定比这更聪明吗?

    有一个假设,即接收缓冲区从不收缩,这是故意不记录的,目的是创建一个精英“游戏中的皮肤”俱乐部,以限制TCP实现的数量。

    有一个假设,即接收缓冲区从不收缩,为了限制TCP实现的数量,故意未经记录的创建精英“游戏中的皮肤”俱乐部。

    “它极大地增加了内存”如何?它所需要的只是套接字接收缓冲区,它已经有了。@Marqueisoflorne我不确定你所说的“它已经有了”是什么意思——我正在实现“它”,所以如果协议不需要它,我就不必浪费内存。但为了回答您的问题,如果窗口无法收回,并且我的(往返时间)x(带宽)是10MB,并且如果我有10K连接,那么我需要100GB的缓冲区。。。或者我永远不能允许一个连接上的所有带宽(因为如果它突然停止,再也不会启动,那么我就永远无法释放10MB的带宽)。这是正在播发的接收窗口,或者更确切地说是其中的可用空间。每个连接的TCP套接字都有一个(和每个UDP套接字)。@洛美侯爵。是,接收窗口正在播发缓冲区。如果窗口端点无法缩回,则缓冲区无法缩回。这正是我的例子。我不知道为什么你看不到,与允许缓冲区在空闲连接上收回相比,这会大大增加内存需求。我已经详细地浏览了这个示例,我不知道为什么您没有看到缓冲区是接收窗口,实现它不是可选的。不清楚你在问什么。“这会大大增加记忆”怎么说?它所需要的只是套接字接收缓冲区,它已经有了。@Marqueisoflorne我不确定你所说的“它已经有了”是什么意思——我正在实现“它”,所以如果协议不需要它,我就不必浪费内存。但为了回答您的问题,如果窗口无法收回,并且我的(往返时间)x(带宽)是10MB,并且如果我有10K连接,那么我需要100GB的缓冲区。。。或者我永远不能允许一个连接上的所有带宽(因为如果它突然停止,再也不会启动,那么我就永远无法释放10MB的带宽)。这是正在播发的接收窗口,或者更确切地说是其中的可用空间。每个连接的TCP套接字都有一个(和每个UDP套接字)。@洛美侯爵。是,接收窗口正在播发缓冲区。如果窗口端点无法缩回,则缓冲区无法缩回。这正是我的例子。我不知道为什么你看不到,与允许缓冲区在空闲连接上收回相比,这会大大增加内存需求。我已经详细地浏览了这个示例,我不知道为什么您没有看到缓冲区是接收窗口,实现它不是可选的。不清楚你在问什么。
      // window update  (https://stackoverflow.com/questions/63931135/)
      int ack_delta = pkt_ack_no - c->tx_sn_ack;
      c->tx_window  = MAX(BE16(PKT.l4.window), c->tx_window - ack_delta);
      if (c->tx_window)
        Net_Notify(); // wake up transmission