慢启动
    刚刚启动的时候不知道网络状况怎么样,所以先悠着一点,每接收到一个ACK后将拥塞窗口翻倍
    但是这种方式每次增长都是指数级的,所以需要配合拥塞避免,不然可能会大量丢包
    拥塞避免
    有一个慢启动阈值,达到这个阈值的时候就会进入拥塞避免状态,拥塞窗口就是线性而不再是指数级的增长,当拥塞避免状态下发生丢包的时候,会有两种情况,一种情况是RTO超时重新发送数据包。这时候会把拥塞窗口设置为初始的MSS,慢启动阈值减半,重新进入慢启动流程。还有一种情况就是接收到了连续的三个ACK,那么TCP会认为这种情况并不算太糟糕,就会进入快速重传和快速恢复阶段。快速重传只会将拥塞窗口和慢启动阈值减半,然后将丢失的数据包重传(一般配合选择性确认,不然不确定哪些包丢了,但是SACK需要两端都确认,FACK),如果在快速恢复期间收到非重复ACK就会重新进入拥塞避免(否则就拥塞窗口+1MSS)
    可用窗口 = 接收,发送,拥塞窗口的最小值
    SACK(选择性确认)可以在前面的报文段还没接收的情况下确认现在接收到的报文段,然后对端能够更精确的重传,而不是全部重传(可以用来优化快重传,tcp_sack打开)
    sack对于攻击来说是个隐患,要遍历哪些数据已经接受了
    还有一种算法不是通过丢包来控制拥塞控制,而是通过测量网络的方式,BBR算法
    当对方窗口为0,发送方会发送窗口探测包让对方回复,如果3次后还是0,直接RST关闭连接(有被攻击的隐患)
    糊涂窗口综合症,对方太忙没有多大的接收空间,腾出几个字节空间发送方就会发送几个字节的空间,导致一直在发送小包,而TCP和IP的头部都有40字节,会导致浪费带宽
    可以使用tcp no delay开启nagle算法,1.等到数据大小超过MSS或者窗口大小超过MSS 2.收到之前的ack包才会发数据(telnet或ssh这样的交互性比较强的程序,你需要关闭这个算法)
    延时ack