TCP windows size decrease because of retransmissions, but not comes back

gsing wrote on Friday, February 23, 2018:

We use freertos + TCP to transmit data from server(zynq) to client(pc), we need high throughput, so I increase the windows size as below:

  /* Fill in the buffer and window sizes that will be used by the socket. */
    xWinProps.lTxBufSize = 16*ipconfigTCP_TX_BUFFER_LENGTH;
    xWinProps.lTxWinSize = 32;
    xWinProps.lRxBufSize = ipconfigTCP_RX_BUFFER_LENGTH;
    xWinProps.lRxWinSize = 8;

With this window size, we can see the throughput can reach 35M+ byte/s, but if unplug/plug cable quickly, after link gets back, the throughput will decease to about 10Mbyte/s.
By debugging, found the windows size decrease because of retransmissions. I think it is reasonable to decrease window size if too many retransmissions. But problem is it will not return to original size after link recover.

below is the code that decease window size:

/* If there have been several retransmissions (4), decrease the
size of the transmission window to at most 2 times MSS. */
if( pxSegment->u.bits.ucTransmitCount == MAX_TRANSMIT_COUNT_USING_LARGE_WINDOW )
    if( pxWindow->xSize.ulTxWindowLength > ( 2U * pxWindow->usMSS ) )
        FreeRTOS_debug_printf( ( "ulTCPWindowTxGet[%u - %d]: Change Tx window: lu%u -> %u\n",
            pxWindow->usPeerPortNumber, pxWindow->usOurPortNumber,
            pxWindow->xSize.ulTxWindowLength, 2 * pxWindow->usMSS ) );
        pxWindow->xSize.ulTxWindowLength = ( 2UL * pxWindow->usMSS );

Thanks for any help!


rtel wrote on Saturday, February 24, 2018:

Looking at the code, I don’ t think there is a way at the moment, other than creating a new socket. If the window size were to increase again then you may get back to the point where re-transmissions occur. Unless the stack records the cause as being an unplug event it doesn’t know why the re-transmissions occurred and so can assume there is some inherent limitation in the network.


heinbali01 wrote on Sunday, February 25, 2018:

Hi Gsing, thanks for reporting this.

While developing FreeRTOS+TCP, we tested the library regularly by connecting a browser to an embedded HTTP-server through a low-quality small-band Internet connection.
The connection would not allow large (1500-byte) packets, and a high percentage of the packets were dropped.
We found that when the TCP send-window size (CWND) was decreased, the performance improved.

The ucTransmitCount variable counts the number of retransmissions per segment. The time-out will double after each retransmission. When 3 retransmissions are done, the window will be made smaller (2 x MSS).

So far so good.

In your case, there is a temporary drop of the link status. After the link status comes up again, the quality will be perfect.

The quickest remedy for you would be to disable the mechanism. And if you have a HTTP-server connected to the Internet, you can keep the TCP window sizes small ( e.g. 3 x MSS ).

It will take some time to add a kind of slow-start algorithm.

gsing wrote on Tuesday, February 27, 2018:

Thanks Richard and Hein,
I don’t have http-server, just transfering data to pc. So I will disalbe this mechanism.
Thanks for the help!