简要复习TCP/IP之运输层(下篇)

一、TCP流量控制

        TCP流量控制是指在数据传输过程中,控制发送方向接收方发送数据的速率,以避免接收方处理不过来而导致数据丢失或拥塞。TCP流量控制通过滑动窗口机制来实现,每次通信两方都在TCP报头的窗口字段写上本端接受缓冲区滑动窗口的值,来告知对方本端能接受多少数据,达到控制对方数据发送速率的目的。

在具体通信过程中:

        首先,通过三次挥手,通信两端获取对方接受缓冲区滑动窗口的初值。

        其次,在接下来的每次通信,都会附上本端滑动窗口的值rwnd。

        如果,在某次通信中一端的滑动窗口值为0,并通过TCP报文告知了对端,那么对端就将不会发送数据报文,两方就都不再知道对方窗口的值了,陷入死锁。为了处理这种情况,当本端滑动窗口值不为0的时候,则应主动发送一条窗口通知报文给对端,并且为防通知报文丢失,对端也应每过一段时间就发送一次窗口请求报文,主动询问本端窗口是否更新了,是否可以发送数据了。值得一提的是,即使本端接收窗口值为0,也必须接受零窗口探测报文段、确认报文段以及携带有紧急数据的报文段,因为滑动窗口为0时不代表接收缓冲区完全满了,而是会预留一段空间专门用来处理TCP报文头,以此来处理零探测报文段等特殊报文段。

 二、TCP拥塞控制

        当同一时间内大量终端向网络发送海量数据时,就可能造成网络堵塞,海量数据报堵塞在路由器内排队甚至直接被丢弃,此时若终端还不断得进行超时重传或发送新的数据报将导致网络更加拥塞,乃至死锁(吞吐量为0)。为了有效地管理网络拥塞,避免上述恶劣情况,TCP实现了一系列的拥塞控制算法,这些算法共同作用完成了TCP的拥塞控制。

  1. 拥塞控制的目标:

    • 避免过载:确保网络不超过其容量负载。
    • 公平性:为不同的连接提供公平的带宽份额。
    • 延迟控制:减少网络延迟,提高性能。
  2. 拥塞指标:

    • 拥塞窗口(Congestion Window,CWND):表示发送方可以发送的未确认数据量。
    • 拥塞窗口大小决定了发送方能够发送的数据量。
    • 拥塞窗口和接收窗口中更小的一项决定发送方实际能发送的数据量。
  3. 慢启动算法(Slow Start):

    • 发送方初始时,将CWND设置为一个较小的值,如2个报文段的大小。
    • 发送方每收到一个确认,CWND加倍。
    • 该算法使得发送方快速适应网络的可用带宽。
  4. 拥塞避免算法(Congestion Avoidance):

    • 当CWND增长到一个阈值(拥塞窗口阈值,ssthresh)时,切换到拥塞避免算法。
    • 发送方每收到一个确认,CWND增加1 / CWND。
    • CWND的线性增长减少了对网络的负载,以避免引发拥塞。
  5. 快速恢复算法(Fast Recovery):

    • 当发生丢包时,发送方认为网络发生拥塞。
    • 发送方将ssthresh设置为CWND的一半,并将CWND设置为ssthresh加上已确认但未发送的数据量。
    • 发送方进入快速恢复状态,在此状态下,每收到一个确认,CWND增加1。
  6. 快速重传算法(Fast Retransmit):

    • 当发送方发现一个报文段丢失时,不必等待超时重传。
    • 如果发送方连续收到3个重复的确认,就认为丢失了下一个报文段,立即重传该报文段。
  7. 超时重传算法:

    • 如果发送方在超时时间内没有收到确认,就认为报文段丢失,重新发送。
    • 超时时间的选择很关键,过长会导致网络吞吐量下降,过短则会频繁触发重传。

总结:

        TCP拥塞控制通过动态调整拥塞窗口大小来控制发送方的发送速率,以避免网络拥塞。慢启动算法和拥塞避免算法共同作用,使发送方根据网络状况逐步增加发送速率,同时避免过载。当发生丢包时,快速恢复算法和快速重传算法能够快速恢复丢失的报文段,而不必等待超时。超时重传算法作为一种备用机制,用于处理异常情况下的报文丢失。

三、面向字节流

重新回顾UDP与TCP的区别:

         UDP中有长度字段可以直接记录整个报文的长度(头部固定为8字节),而TCP中只有首部长度字段,这意味着TCP协议根本并不关心数据报的长度,更进一步说明了TCP不关心数据在缓冲区中的存放情况。

        UDP是面向报文的,它没有严格意义上的“缓冲区”(实际上还是有存放报文的地方的),它只允许数据按一个报文一个报文的交付,有很明确的数据边界。站在应用层的角度来看, 使用UDP的时候, 要么收到完整的UDP报文, 要么不收,不会出现""的情况。

        TCP则不同,应用层下达的数据和网络层上达的数据存储在对应的缓冲区中,它是按字节传输数据的,应用层下达数据报或者网络层上达数据报给TCP时,TCP是没有必要按照原本的报文长度进行传输的,而是统一将数据加入缓冲区中,之后到底是分几次传输,一次传输多少字节,取决于TCP的“自我决断”。在缓冲区中数据是“粘成一串的”,彼此之间无法分隔。需要依靠应用层的解析才能够从“粘成一串”的数据流将数据分隔开来。

        以http协议为例,http报头中依靠'\n'字符来分隔不同的报头属性段,而报头与报文体之间还要依靠一个'\n'来分隔,用户可以根据'\n'来将从运输层上达的字节流分隔成http协议原本的内容。但是在运输层'\n'也只是个普通字节数据,TCP协议本身是不对字节流进行分割分类的,多个http数据包是完全连在一块的,这就是粘包问题。

那么如何避免粘包问题呢?

归根结底就是一句话, 明确两个包之间的边界:

  •         对于定长的包, 保证每次都按固定大小读取即可,如以一个固定大小的结构体的长度进行读取;
    •         对于变长的包, 可以在包头的位置, 约定一个包总长度的字段, 从而就知道了包的结束位置;
      •         对于变长的包, 还可以在包和包之间使用明确的分隔符(应用层协议, 是程序猿自己来定的, 只要保证分隔符不和正文冲突即可,例如http协议)。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值