美文网首页
网络协议-- 底层网络知识详解(传输层)

网络协议-- 底层网络知识详解(传输层)

作者: zhujunhua | 来源:发表于2020-09-18 09:23 被阅读0次

    UDP

    UDP包头

    UDP 的三大特点

    • 沟通简单
      它相信网络世界是美好的,秉承性善论,相信网络通路默认就是很容易送达的,不容易被丢弃的。
    • 轻信他人
      虽然有端口号,但是监听在这个地方,谁都可以传给他数据,他也可以传给任何人数据,甚至可以同时传给多个人数据。
    • 愣头青,做事不懂权变
      它不会根据网络的情况进行发包的拥塞控制,无论网络丢包丢成啥样了,它该怎么发还怎么发。

    UDP 的三大使用场景

    • 需要资源少,在网络情况比较好的内网,或者对于丢包不敏感的应用
    • 不需要一对一沟通,建立连接,而是可以广播的应用
      DHCP 就是一种广播的形式,就是基于 UDP 协议的。
    • 需要处理速度快,时延低,可以容忍少数丢包,但是要求即便网络拥塞,也毫不退缩,一往无前的时候

    基于 UDP 的“城会玩”的五个例子

    • “城会玩”一:网页或者 APP 的访问
      QUIC(全称 Quick UDP Internet Connections,快速 UDP 互联网连接)是 Google 提出的一种基于 UDP 改进的通信协议,其目的是降低网络通信的延迟,提供更好的用户互动体验。
      QUIC 在应用层上,会自己实现快速连接建立、减少重传时延,自适应拥塞控制,是应用层“城会玩”的代表。这一节主要是讲 UDP,QUIC 我们放到应用层去讲。
    • “城会玩”二:流媒体的协议
      很多直播应用,都基于 UDP 实现了自己的视频传输协议。x
    • “城会玩”三:实时游戏
      游戏对实时要求较为严格的情况下,采用自定义的可靠 UDP 协议,自定义重传策略,能够把丢包产生的延迟降到最低,尽量减少网络问题对游戏性造成的影响。
    • “城会玩”四:IoT 物联网
      一方面,物联网领域终端资源少,很可能只是个内存非常小的嵌入式系统,而维护 TCP 协议代价太大;另一方面,物联网对实时性要求也很高,而 TCP 还是因为上面的那些原因导致时延大。Google 旗下的 Nest 建立 Thread Group,推出了物联网通信协议 Thread,就是基于 UDP 协议的。
    • “城会玩”五:移动通信领域
      在 4G 网络里,移动流量上网的数据面对的协议 GTP-U 是基于 UDP 的。因为移动网络协议比较复杂,而 GTP 协议本身就包含复杂的手机上线下线的通信协议。如果基于 TCP,TCP 的机制就显得非常多余,这部分协议我会在后面的章节单独讲解。

    TCP

    TCP协议之所以这么复杂,那是因为它秉承的是“性恶论”。它天然认为网络环境是恶劣的,丢包、乱序、重传,拥塞都是常有的事情,一言不合就可能送达不了,因而要从算法层面来保证可靠性。


    TCP包头

    状态位。例如 SYN 是发起一个连接,ACK 是回复,RST 是重新连接,FIN 是结束连接等。TCP 是面向连接的,因而双方要维护连接的状态,这些带状态位的包的发送,会引起双方的状态变更。
    窗口大小。TCP 要做流量控制,通信双方各声明一个窗口,标识自己当前能够的处理能力,别发送的太快,撑死我,也别发的太慢,饿死我。

    TCP 的三次握手

    我们常称为“请求 -> 应答 -> 应答之应答”的三个回合。
    三次握手除了双方建立连接外,主要还是为了沟通一件事情,就是 TCP 包的序号的问题。
    为什么序号不能都从 1 开始呢?因为这样往往会出现冲突。


    建立连接的状态时序图

    一开始,客户端和服务端都处于 CLOSED 状态。先是服务端主动监听某个端口,处于 LISTEN 状态。然后客户端主动发起连接 SYN,之后处于 SYN-SENT 状态。服务端收到发起的连接,返回 SYN,并且 ACK 客户端的 SYN,之后处于 SYN-RCVD 状态。客户端收到服务端发送的 SYN 和 ACK 之后,发送 ACK 的 ACK,之后处于 ESTABLISHED 状态,因为它一发一收成功了。服务端收到 ACK 的 ACK 之后,处于 ESTABLISHED 状态,因为它也一发一收了。

    TCP 四次挥手

    断开连接的状态时序图

    TCP状态机

    TCP状态机

    在这个图中,加黑加粗的部分,是上面说到的主要流程,其中阿拉伯数字的序号,是连接过程中的顺序,而大写中文数字的序号,是连接断开过程中的顺序。加粗的实线是客户端 A 的状态变迁,加粗的虚线是服务端 B 的状态变迁。

    总结:
    TCP 包头很复杂,但是主要关注五个问题,顺序问题,丢包问题,连接维护,流量控制,拥塞控制;
    连接的建立是经过三次握手,断开的时候四次挥手,一定要掌握那几个状态图。

    如何实现一个靠谱的协议?

    TCP 协议使用的也是同样的模式。为了保证顺序性,每一个包都有一个 ID。在建立连接的时候,会商定起始的 ID 是什么,然后按照 ID 一个个发送。为了保证不丢包,对于发送的包都要进行应答,但是这个应答也不是一个一个来的,而是会应答某个之前的 ID,表示都收到了,这种模式称为累计确认或者累计应答(cumulative acknowledgment)

    为了记录所有发送的包和接收的包,TCP 也需要发送端和接收端分别都有缓存来保存这些记录。发送端的缓存里是按照包的 ID 一个个排列,根据处理的情况分成四个部分。

    • 第一部分:发送了并且已经确认的。这部分就是你交代下属的,并且也做完了的,应该划掉的。
    • 第二部分:发送了并且尚未确认的。这部分是你交代下属的,但是还没做完的,需要等待做完的回复之后,才能划掉。
    • 第三部分:没有发送,但是已经等待发送的。这部分是你还没有交代给下属,但是马上就要交代的。
    • 第四部分:没有发送,并且暂时还不会发送的。这部分是你还没有交代给下属,而且暂时还不会交代给下属的。


      发送端

    在 TCP 里,接收端会给发送端报一个窗口的大小,叫 Advertised window。这个窗口的大小应该等于上面的第二部分加上第三部分。超过这个窗口的,接收端处理不过来,就不能发送了。

    对于接收端来讲,它的缓存里记录的内容要简单一些。

    • 第一部分:接受并且确认过的。也就是我领导交代给我,并且我做完的。
    • 第二部分:还没接收,但是马上就能接收的。也即是我自己的能够接受的最大工作量。
    • 第三部分:还没接收,也没法接收的。也即超过工作量的部分,实在做不完。


      接收端

    顺序问题和丢包问题

    • 一种方法就是超时重试,也即对每一个发送了,但是没有 ACK 的包,都有设一个定时器,超过了一定的时间,就重新尝试。

    • 有一个可以快速重传的机制,当接收方收到一个序号大于下一个所期望的报文段时,就会检测到数据流中的一个间隔,于是它就会发送冗余的 ACK,仍然 ACK 的是期望接收的报文段。而当客户端收到三个冗余的 ACK 后,就会在定时器过期之前,重传丢失的报文段。

    例如,接收方发现 6 收到了,8 也收到了,但是 7 还没来,那肯定是丢了,于是发送 6 的 ACK,要求下一个是 7。接下来,收到后续的包,仍然发送 6 的 ACK,要求下一个是 7。当客户端收到 3 个重复 ACK,就会发现 7 的确丢了,不等超时,马上重发。

    • 还有一种方式称为 Selective Acknowledgment (SACK)。这种方式需要在 TCP 头里加一个 SACK 的东西,可以将缓存的地图发送给发送方。例如可以发送 ACK6、SACK8、SACK9,有了地图,发送方一下子就能看出来是 7 丢了。

    总结:
    顺序问题、丢包问题、流量控制都是通过滑动窗口来解决的,这其实就相当于你领导和你的工作备忘录,布置过的工作要有编号,干完了有反馈,活不能派太多,也不能太少;
    拥塞控制是通过拥塞窗口来解决的,相当于往管道里面倒水,快了容易溢出,慢了浪费带宽,要摸着石头过河,找到最优值。

    Socket

    参考:
    极客时间-趣谈网络协议

    相关文章

      网友评论

          本文标题:网络协议-- 底层网络知识详解(传输层)

          本文链接:https://www.haomeiwen.com/subject/mnjhyktx.html