UDP 协议格式及应用
Posted vector6_
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UDP 协议格式及应用相关的知识,希望对你有一定的参考价值。
UDP 协议格式及应用
在IP层之上为传输层,最重要的两个协议是TCP和UDP,也是我们接触最多且熟悉的,本文将对UDP协议格式、特性及相关应用场景进行分析。
TCP 和 UDP 有哪些区别?
首先我们都知道,TCP 是面向连接的,UDP 是面向无连接的。那么什么叫面向连接,什么叫无连接呢?在互通之前,面向连接的协议会先建立连接。例如,TCP 会三次握手,而 UDP 不会。为什么要建立连接呢?
TCP/UDP建立连接的本质就是在客户端和服务端各自维护一定的数据结构(一种状态机),来记录和维护这个“连接”的状态 (双方交互的状态)。并不是真的会在这两个端之间有一条类似“网络专线”这么一个东西。
而建立连接的目的其实就是TCP为了提供UDP 之外的一些保障可靠性的特性。
例如,TCP 提供可靠交付。通过 TCP 连接传输的数据,无差错、不丢失、不重复、并且按序到达。我们都知道 IP 包是没有任何可靠性保证的,一旦发出去,不论是否丢失都只能随它去。但是 TCP 号称能做到那个连接维护的程序做的事情。而 UDP 继承了 IP 包的特性,不保证不丢失,不保证按顺序到达。
再如,TCP 是面向字节流的。发送的时候发的是一个流,没头没尾。而IP层不是流是一个个的 IP 包。之所以变成了流,这也是 TCP 自己的状态维护做的事情。而 UDP 继承了 IP 的特性,基于数据报的,一个一个地发,一个一个地收。
并且TCP 是有拥塞控制机制。若检测到包丢弃了或者网络环境不好,就会根据情况调整发包的速率。而UDP 就没有支持这样的机制,只按照应用的要求发送。
因而 TCP 其实是一个有状态服务,而 UDP 则是无状态服务。
我们可以这样比喻,如果 MAC 层定义了本地局域网的传输行为,IP 层定义了整个网络端到端的传输行为,这两层基本定义了这样的基因:网络传输是以包为单位的,二层叫帧,网络层叫包,传输层叫段。我们笼统地称为包。包单独传输,自行选路,在不同的设备封装解封装,不保证到达。基于这个基因,生下来的孩子 UDP 完全继承了这些特性,几乎没有自己的思想。
UDP 包头格式
我们知道数据包传输的流程:当我发送的 UDP 包到达目标机器后,发现 MAC 地址匹配,于是就取下来,将剩下的包传给处理 IP 层的代码。把 IP 头取下来,发现目标 IP 匹配,接下来要判断这个包是UDP还是TCP,所以IP 头里面有个 8 位协议,这里会存放,数据里面到底是 TCP 还是 UDP。若这里是UDP,知道UDP 头的格式,就能从数据里面,将它解析出来,之后需要将数据交给对应的应用程序,所以无论是 TCP 还是 UDP 包头里面应该有端口号,根据端口号,将数据交给相应的应用程序。以下是UDP头部及负载(数据)区。
PS:因为IP层根据IPv4头部中的协议字段将进入的IP数据报分离到特定的传输协议,这意味着端口号在不同的传输协议之间是独立的;也就是说,TCP端口号只能被TCP使用,UDP端口号只能被UDP使用,如此类推。这样的分离导致的一个直接结果是两个完全不同的服务器可以使用相同的端口号和IP地址,只要他们使用的不同的传输协议。(尽管有这样的独立性,但是如果某个众所周知的服务可同时由TCP和UDP提供,那么这两个传输协议的端口号通常被分配成一样的)
UDP校验和
我们知道IPv4头部的校验和只覆盖整个头部(即它并不覆盖IP分组中的任何数据),它在每个IP跳都要被重新计算(因为IPv4 TTL字段的值在数据报转发时会被路由器减少)。
而传输协议(TCP/UDP)使用校验和来覆盖它们的头部和数据。对于UDP的校验和,它覆盖了UDP头部、UDP数据和一个伪头部(衍生自IPv4 头部的字段,伪头部也是虚的,它的目的只是用于校验和计算,它不会被发送出去)。它由初始的发送方计算得到,由最终的目的方校验,在传送过程中不会被修改。
UDP的校验和是可选的,当然默认是使用的。
[RFC1122] 要求UDP校验和被默认使用,不过进来已有一些对UDP校验和的松懈使用,主要是一些对差错不完全看中的应用(例如多媒体应用)。这关系到部分校验和即校验和只覆盖由应用程序指定的负载的一部分,例如UDP-Lite。
UDP-Lite
有些应用程序可以容忍在发送和接受的数据里引入的比特差错。通常,为了避免建立连接的开销或者为了使用广播或组播地址,这类应用汇选择使用UDP,但是UDP使用的校验和要么覆盖整个负载,要么就一点也没有,这很可能无法达到该类应用的要求。
而UDP-Lite 的协议通过修改传统的UDP协议,提供了部分校验和来解决这个问题。这些校验和只覆盖每个UDP数据报里的一部分负载。UDP-Lite 用一个校验和覆盖范围(Checksum Coverage)字段取代了长度字段来修改UDP头部。
上图中校验和覆盖范围字段是被校验和覆盖的字节数(从UDP-Lite头部的第一个字节开始)。除了特殊的值0以外,最小值是8,因为UDP-Lite 头部自身总是要求被校验和覆盖的。值0表示整个负载都被校验和覆盖,这就和传统UDP一样了。可以使用一些特殊的套接字API选项为应用程序指明使用UDP-Lite(IPPROTO_UDPLITE)和要求 的校验和覆盖范围的数量(使用 setsockopt 的 SOL_UDPLITE、UDPLITE_SEND_CSCOV 和 UDPLITE_RECV_CSCOV 选项)。
UDP 的特点
由上面的分析我们可以得到UDP的特点主要有:
- 数据报简单,没有维护大量的数据结构、包头字段。
- 无连接,传输开销小,虽然有端口号,但是监听在这个地方,谁都可以传给他数据,他也可以传给任何人数据,甚至可以同时传给多个人数据。
- 不对网络传输进行监测控制,没有差错纠正、队列管理、重复消除、流量控制、拥塞控制等机制。当然,这可以根据应用程序的需要选择实现合适的重传单元能力。
UDP的使用场景
基于 UDP 这些特点,我们可以考虑在以下的场景中使用。
- 需要资源少,在网络情况比较好的内网,或者对于丢包不敏感的应用。例如DHCP 就是基于 UDP 协议的。一般的获取 IP 地址都是内网请求,而且一次获取不到 IP 又没事,过一会儿还有机会。
- 不需要一对一沟通,建立连接,而是可以广播的应用。UDP 的不面向连接的功能,可以使得可以承载广播或者多播的协议。DHCP 就是一种广播的形式,就是基于 UDP 协议的。
- 需要处理速度快,时延低,可以容忍少数丢包,但是要求即便网络拥塞,也不会降低发送速率的时候。UDP 简单、处理速度快,不像 TCP有众多的传输控制机制,也导致了TCP时延相对较高,并且TCP在网络不好出现丢包的时候,拥塞控制策略会主动的退缩,降低发送速度。多用于实时游戏中,游戏对实时要求较为严格的情况下,采用自定义的可靠 UDP 协议,自定义重传策略,能够把丢包产生的延迟降到最低,尽量减少网络问题对游戏性造成的影响。除此之外很多直播应用,都基于 UDP 实现了自己的视频传输协议。
以上是关于UDP 协议格式及应用的主要内容,如果未能解决你的问题,请参考以下文章
UDP协议详解(UDP协议特点,UDP协议格式UDP的应用)