TCP的核心设计理念

TCP的核心设计理念:

  1. 保证可靠性传输。
  2. 尽可能的提高传送效率。 提高效率的前提是保证可靠性。保证可靠性就必须能及时的发现自己发送的数据是发送成功了还是失败了。

    1. 确认应答

    确认应答
    在确认应答机制中,TCP将每一个字节的数据都进行了编码(序号),每一个ACK都带有对应的确认序列号(这里的序号不是从1开始的,是通过建立链接的时候协商出来的从哪里开始), 意思是告诉发送者, 我已经收到了哪些数据; 下一次你从哪里开始发.

2.超时重传机制

超时重传
主机A发送给主机B一段数据,因为网络拥堵等各种原因发生丢包,主机B没有收到主机B,发送给它的数据。主机A在等待了特定的时间之后也没有收到主机B发回的ACK,主机A会进行重新发送。
如果主机B收到了主机A第二次发生的数据,会发回对应的ACK,但是如果网络一直拥堵,主机B一直收不到主机A发送的数据,主机A会每隔一段特定的时间进行重传,而超时时间会一次变长(采用一种悲观特态度面对丢包)。如果累计重传此时到一定的次数,TCP认为网络或者对端主机出现异常,强制关闭连接。

自动去重:以上提到的情况都是发送的数据丢包,但是也有可能会是接收端发回的取人应答ACK发送丢包,发送端会一直进行超时重传,这种情况下接收端会收到无数重复的数据,此时上面提到的对TCP对传输的数据进行的编码(序号)就派上了用途,接收端会发回相同的ACK,保证传输数据的可靠性。

3.连接管理 (单独总结)

  • 建立连接(三次握手)
  • 断开连接(四次挥手)

4. 提高传输效率

tcp传输中客户端每发送一个数据,都要等待服务器返回一个ACK,才能继续发送数据
TCP多次应答
如图,很明显如果对TCP传输不进行优化的化,客户端和服务器花费在等待应答上的时间就比较多,这样效率就比较低了,所以就出现了优化效率的方法批量发送数据(滑动窗口)。
滑动窗口

  • 滑动窗口就是批量化的发送数据,批量发送的数据量称为窗口的大小 如图的窗口大小为4000个字节
  • 发送前4段的时候无需等待ACK直接发送
  • 收到第一个ACK之后滑动窗口向后移动,继续发送第5段数据,一次类推
  • 操作系统内核为了维护这个滑动窗口,需要开辟一段发送缓冲区来记录还有那些数据没有应答,只有确认过应答的数据,才能从缓冲区删除,没有收到ACK的数据随时会触发超时重传
  • 窗口越大,网络吞吐率就越高,但是窗口也不能无限大(要保证可靠性)。

    发生方发生的数据先到达接收方的网卡,然后放到内核中的接受缓冲区中,接受方的用户代码从缓冲区中读取数据(recv/read)
    滑动窗口的方式传输发生丢包的话会有两种可能:

  • 数据包丢了(快速重传):
    (转)滑动窗口丢数据
    和超时重传本质上是一样的,借助确认序号的特点,能够做到只传丢了的那一个数据,其他正确到达的数据无需重复传输
  • 数据包已经抵达,但是ACK丢了:
    滑动窗口丢ACK
    这种情况可以选择无视掉,可以通过后续的ACK进行确认校验。

5. 保证可靠性(控制窗口大小)

1.流量控制

发生方如果发的比较快接收方处理不过来。
在这里插入图片描述
用接受缓冲区的剩余空间大小作为指标来衡量接收端的处理能力。TCP协议报头中有一个窗口大小字段,这个字段是和接受缓冲区的空余大小相关联的。如果接受缓冲区空余空间大小是1K,此时这个窗口大小字段也是1K,建议发送按照1K这样的窗口大小来发送。

2. 拥塞控制

如果当前网络比较拥堵,发生方如果发生的很快,仍然会丢包。
根据丢包情况作为判断依据,如果出现丢包,认为网络比较堵塞。如果没有丢包,认为网络比较畅通。

  • 慢开始:开始的时候按照比较小的窗口来发送数据
  • 如果没有丢包,就按照指数的形式提升窗口大小
  • 如果窗口大小到达一定的阈值之后,而是按照线性增长
  • 窗口达到一定的大小之后,机会发生丢包,一旦发生丢包,认为网络拥堵,就把窗口大小一下就设回一个非常小的值回复满开始的过程
    拥塞控制

    6.延时应答

    提高传输效率,和滑动窗口相关,在保证可靠性的前提下让滑动窗口尽可能的大。
    如果接受数据的主机立即发回ACK应答,这个时候返回的窗口可能比较小
  • 假设接收端缓冲区为1M,一次收到了500K的数据;如果立即应答,返回的窗口就是500k
  • 但是实际上可能处理端处理的数度是很快的,10ms之内就能把500k数据从缓冲区消费掉
  • 这种情况下,接收端处理远没有达到自己的极限,即使窗口在大一些,也能处理过来
    如果接收端稍微等一会应答,比如等待200ms再应答,那么这个时候返回的窗口大小就是1M