头图

综述

网络层的 IP 协议为主机之间提供了逻辑通信,而 IP 的服务模型是尽力而为提供服务。这就意味着 IP 尽力在主机之间交付报文,但是它并不做任何保证。不确保报文段的交付,不保证报文段的按序交付,也不保证报文段中数据的完整性。所以 IP 是不可靠的服务

而运输层 (TCP 和 UDP) 将两个端系统间的 IP 的交付服务扩展为运行在端系统上的两个进程间的交付服务。而 UDP 仅提供了进程到进程的数据交付和差错检查两种服务,所以 UDP 也是一种不可靠的服务

TCP 和 UDP 的对比

“TCP 是面向连接的,而 UDP 是无连接的”

建立连接指的是,为了在客户端和服务端维护连接,而建立一定的数据结构来维护双方交互的状态,用这样的数据结构来保证所谓的面向连接的特性。

面向连接的意思是,在互通之前,面向连接的协议会先建立连接,例如 TCP 会进行三次握手,而 UDP 不会。使用 UDP 时,在发送报文之前,发送方和接收方的运输实体之间没有握手,如此 UDP 才被称为是无连接的。
所以 TCP 和 UDP 的不同之处,主要体现在下面几个方面:

  • 可靠交付。通过 TCP 传输的数据,无差错、不丢失、不重复、并且按序到达。而 UDP 继承了 IP 包的特性,不保证不丢失,不保证按顺序到达
  • 面向对象不同。TCP 是面向字节流的,发送的时候是一个流,没头没尾。而之所以发送的是流,也是 TCP 自己的状态维护做的事情。但是 UDP 继承了 IP 包的特性,是基于数据包的,一个一个地发,一个一个地收
  • 拥塞控制。TCP 有自己地拥塞控制机制,当它意识到包丢弃了或者是网络不好了,就会根据情况调整自己地行为,例如降低发送速度。而 UDP 没有拥塞控制,只会根据应用层地指令发包,即便是网络环境差,只要上层有指令发包,就会一直发
  • 有无状态。TCP 通过给数据编号,精确地记录了某个数据发送了没有,接收到没有,发送到哪个了,应该接收哪个。而 UDP 则是无状态的,不记录发送的包的信息

UDP 包的结构

image.png

UDP 包是无连接的,那么首次发送 UDP 包时,目的端口号如何得知?服务器上的服务,使用的是 1024 以内的周知端口号,例如 DNS 服务器,那么源主机发送 UDP 时在目的端口号处填写 53 即可。(但是总感觉这个原因逻辑性不强)

解析 UDP 包之前的动作:接收方收到一个包之后,会先查看目的 MAC 地址和自己的 MAC 地址是否一致。若一致就把 MAC 头部取下来,再把剩下的部分交给 IP 层。IP 层取下 IP 头部之后,若发现目的 IP 地址和自己的 IP 地址相同,然后再查看 IP 头部里的协议类型,发现 IP 数据包的部分是 UDP 协议。于是就开始解析 UDP 包。将 UDP 包解析出来之后,查看头部的目的端口号,然后把里面的数据交给监听这个端口的某个应用处理。

UDP 的特点

  • 结构简单。UDP 的头部只有源端口和目的端口,以及报文长度和校验和,除此之外就是数据部分了。如此应用层就可以进行精确的控制
  • 它不会建立连接,虽然有端口号,但是监听时,谁都可以传给他数据,他也可以传给任何人数据,甚至可以同时传给多个人数据
  • 无连接状态。TCP 需要维护连接状态,包括接收和发送缓存、拥塞控制参数以及序号与确认号的参数。而 UDP 不维护连接状态,也就没有这些参数。所以运行在 UDP 之上的服务器一般都能支持更多的活跃用户
  • 首部开销小。UDP 首部只有 8 个字节,而 TCP 有 20 个字节

UDP 应用场景

  1. 需要资源少,网络情况好的内网;或者是对于丢包不敏感的应用。例如使用 DHCP ,获取 IP 一般都是在内网进行,就算数据包没有到达,因为是内网,所以也无影响。还有 PXE 安装操作系统时,使用 TFTP 下载操作系统也是使用的 UDP,因为此时客户机还没有操作系统,拥有的资源很少,难以维护较为复杂的 TCP
  2. 不需要进行一对一沟通、建立连接,可以广播的应用。UDP 无连接,所以可以应用在广播或者多播的协议中。上述提到的 DHCP 就是广播
  3. 需要处理速度快,时延低,可以容忍少数丢包,但是要求即便网络拥塞,也必须发包的时候。UDP 结构简单,处理速度快,不像 TCP 要保证顺序、还需要重传,因为这会增加时延。而且 UDP 没有拥塞控制,即便网络状况不好,也会发包。而 TCP 此时就会降低发送速度,使得原本卡顿的应用变得更加卡顿。

因为 UDP 结构简单,所以可以由应用自己做一些工作,并利用 UDP 速度快低时延、结构简单的特性,进而开发自定义的应用:

  1. 网页或 APP 的访问。原先的网页和 APP 都是基于 HTTP 协议的,而 HTTP 协议是基于 TCP 的。建立连接时需要多次交互,就造成了时延较高的情况。此外手机处于移动过程中,TCP 可能会断开连接,进行重连又会增加时延。而且目前的 HTTP 协议,往往采取多个数据通道共享一个连接的情况,这样本来为了加快传输速度,但是 TCP 的严格顺序策略使得哪怕共享通道,前一个不来,后一个和前一个即便没关系,也要等着,时延也会加大

    Chrome 中使用的 QUIC 协议,将 UDP 作为支撑运输协议并在 UDP 之上的应用层协议中实现可靠性
  2. 流媒体协议。直播协议多使用 RTMP 协议,而这个协议也是基于 TCP 的。TCP 严格保证数据的顺序性对于直播是不合适的,因为老的视频帧丢了其实也就丢了,就算再传过来用户也不在意了,他们要看新的了。如果老是没来就等着,卡顿了,新的也看不了。所以直播,实时性比较比较重要,宁可丢包,也不要卡顿的。当网络不好的时候,TCP 协议会主动降低发送速度,这就使得原本卡顿的视频更加卡顿。实际上,应用层应该马上重传,而不是主动让步

    以下是关于视频帧的说明。视频都是由一张一张的图片形成的,快速播放一组图片也就形成了视频,一张图片在视频里叫做一帧。保存视频时,并不是将每一帧都完整保存,而是保存与上一帧的不同之处,从而降低占用的存储空间。理论上,可以只保留视频的第一帧,以后都保存相较于第一帧的变化。但实际中会隔几帧就保存一整个帧,目的是为了防止传输中出现错误。

    这个原理相当于保存 [1000, 1001, 1002, 1003, 1004] 这个数组时,若按照 [1000, 1, 1, 1, 1] 的形式保存,1000 以后的项都保存与前一项之间的大小差距,那么将节省很多存储空间

  3. 实时游戏。游戏对时效性的要求比较高,实时游戏中客户端和服务端要建立长连接,来保证实时传输。维护 TCP 连接需要在内核维护一些数据结构,因而一台机器能够支撑的 TCP 连接数目是有限的,当玩家数量增多之后,一台机器就不够用了。而 UDP 是没有连接的,在异步 IO 机制引入之前,常常是应对海量客户端连接的策略。另外还是 TCP 的强顺序问题,对战游戏中,客户端发送给服务器鼠标和键盘行走的位置,服务器会处理每个用户发送过来的所有场景,处理完再返回给客户端,客户端解析响应,渲染最新的场景展示给玩家。如果出现一个数据包丢失,所有事情都需要停下来等待这个数据包重发。客户端会出现等待接收数据,然而玩家并不关心过期的数据。游戏对实时要求较为严格的情况下,采用自定义的可靠 UDP 协议,自定义重传策略,能够把丢包产生的延迟降到最低,尽量减少网络问题对游戏性造成的影响。
  4. Iot 物联网。一方面,物联网领域终端资源少,很可能只是个内存非常小的嵌入式系统,而维护 TCP 协议代价太大;另一方面,物联网对实时性要求也很高,而 TCP 还是因为上面的那些原因导致时延大
  5. 移动通信领域。在 4G 网络里,移动流量上网的协议 GTP-U 就是基于 UDP 的。因为移动网络协议比较复杂,而 GTP 协议本身就包含复杂的手机上线下线的通信协议。如果基于 TCP,TCP 的机制就显得非常多余

半岛酒店
1 声望0 粉丝

文章都是学习极客时间上的专栏的笔记,还有啃书时候书上的内容,侵删


引用和评论

0 条评论