35_简单快捷不可靠的_UDP
网络协议那些事儿
内容简介
-
前言
-
两种协议,TCP 和 UDP
-
简单快捷不可靠的 UDP 协议
-
前言
上一课我们学习了 port(端口),它是用于标识机器上的 application(应用程序)的 "地址"。
现在,就让我们来学习著名的 UDP 和 TCP 协议。这两个协议也是程序员面试的时候经常会被问到的知识点,所以好好来学习吧。
- 两种协议,TCP 和 UDP
在 OSI 第 2 层和第 3 层中,我们都只看到一种数据传输协议(第 2 层为 Ethernet(以太网)协议 ,第 3 层为 IP 协议)。
那么,为什么 OSI 第 4 层需要两个协议呢?
那是因为网络领域的先驱们意识到传输应用程序的数据应该有两类不同的需求:
- 第一类是需要可靠地传输数据但对传输速度没有特殊要求的应用程序;
- 第二类是需要立即传输数据但允许传输时丢失一些信息的应用程序。
你是否知道属于上面第一类和第二类的应用程序的例子?
第一类包括绝大多数互联网应用程序,因为其中许多应用程序要求不惜一切代价接收每个发送的数据包!这样的应用程序包括 Web 应用程序,电子邮件应用程序,SSH 软件,大多数在线游戏,等等。对于网页来说,如果丢失一个数据包,页面就无法正确显示。对于电子邮件来说也是如此。
第二类包括的应用程序比第一类少,但你很快会明白为什么这些应用程序需要即刻的传输以及可以允许发送的某些包没有被收到。这样的应用程序包括流媒体应用程序,例如互联网广播或电视。对于在线广播,至关重要的是尽快地实时发送信息。如果丢失一个或多个数据包,我们并不会停止广播。用户可能会听到广播断断续续的,但广播将继续播放。
因此,我们确定了非常不同的两个需求:
- 可靠的协议,但不需要很快速;
- 快速的协议,但不需要可靠性。
这就是为什么我们在第 4 层有两个协议(TCP 协议和 UDP 协议)的原因。
TCP 协议属于第一类,它是一种非常可靠的协议。发送的每一个数据包都必须被接收方确认接收才行,如果接收方的接收确认没有返回,发送方将会重新发送此数据包。我们说 TCP 是面向连接(Connection-Oriented)的协议。
我们可以用打电话来做比方。当我们打电话给某人时,我们会说 "Hello ?" (Hello 表示 "喂,您好,你好"),以确认此人是否在那儿。如果通话过程中有沉默,我们会询问对方是否还在听,等等。TCP 协议也是类似的,对于发送的每个信息,我们将确认另一端的机器是否已接收到此信息。
UDP 协议是一种快速但不可靠的协议。数据包会尽快被发送,但我们不在乎数据包是否被收到。我们说 UDP 是一个无连接(Connectionless)的协议。这有点像信件(虽然信件不够快...),我们先寄信,然后迫切祈祷信能够寄到,却并不能保证一定可以如愿。
我们首先来学习 UDP 协议。
- 简单快捷不可靠的 UDP 协议
UDP 是 User Datagram Protocol 的缩写,表示 "用户数据报协议"。user 表示 "用户",datagram 表示 "数据报",protocol 表示 "协议"。
UDP 是很简单的协议。由于 UDP 的目标是速度,并不需要知道信息是否被正确接收,因此发送的报文的格式是非常简单的。
UDP 数据报
是的,我们称呼 UDP 协议的报文(message,也可以称为 "消息")为数据报(datagram),正如称呼 OSI 第 3 层的 IP 协议的报文为数据报一样。这是正常的,因为数据报大体来说就代表了这样一种报文,我们对此报文的正确发送或接收一无所知。
以下是 UDP 数据报的格式:

可以看到,UDP 数据报的头部(可以简称为 "报头")只有四个区域:源端口号,目标端口号,总长度,Checksum。
每个区域都占 2 个字节,所以头部只需要 8 个字节。这是我们迄今为止看到的最小的头部了,以后应该也看不到比这更小的头部了。
让我们逐一学习这些区域:
-
源端口号(Source Port):这很简单,它是发送信息的应用程序的地址。
-
目标端口号(Destination Port):也很简单,它是接收信息的应用程序的地址。
-
数据报的总长度(单位是 Byte,byte 表示 "字节",一个字节是 8 位二进制位,也就是 8 个 bit):此区域占 2 字节(16 位二进制位),这意味着一个数据报的最大长度是 2 的 16 次方(等于 65536)个字节。但现实中,很少见到大于 512 字节的 UDP 数据报。这主要是因为丢失一个较小的数据报是可以接受的,但是丢失较大的数据报则比较麻烦,因为 UDP 对于丢失数据包置若罔闻。
-
Checksum:表示 "校验和",其原理与 OSI 第 2 层的以太网帧里的 CRC(循环冗余校验)类似,也是为了确保发送的数据和接收的数据是相同的。也许有些教材将这里的 Checksum 写成 CRC。CRC 和 Checksum 都属于冗余校验(Redundancy Check)。Checksum 是最简单的冗余校验。
对于 Checksum 这个用于校验的区域,我们不禁要发问:"既然 OSI 第 2 层以太网协议已经有一个 CRC 校验了,为什么 UDP 协议还需要有一个 Checksum 校验呢?"。
事实上,如果你理解了封装的原理,你就会知道 UDP 数据报是位于以太网帧里面的,因此以太网帧的 CRC 校验的是第 4 层 UDP 协议的数据。
那么,为什么要执行两次校验呢?
答案就在于 OSI 模型。如果你还记得的话,与 OSI 模型相关的规则之一就是 "每一层都是独立的"。因此,第 2 层以太网协议执行了校验,并不意味着第 4 层就不应该执行校验,同理对第 3 层也是一样。因为每一层都不应该知道另一层执行了一个校验,每个层应该实现自己的校验。
此外,网络领域的 "圣经"《TCP/IP 详解》(TCP/IP Illustrated)的作者 Richard Stevens 在此系列丛书的第 1 卷(Volume 1)中向我们展示过,有时数据报到达第 4 层时,会带着从第 3 层跨越到第 4 层时产生的错误。因此,使用冗余校验是非常必要的。
使用 UDP 的应用程序
绝大多数流媒体应用程序都使用 UDP,例如互联网广播,互联网电视,等。UDP 也被用于互联网电话,即 VoIP(VoIP 是 Voice over Internet Protocol,表示 "基于 IP 协议的语音传输"),有时也被称为 ToIP(Telephony over IP,表示 "基于 IP 协议的电话业务")。
我们也使用 UDP 来传输 DNS 和 SNMP 这两个协议的数据。不用担心,我们将在以后的课程中学习这两个协议。
那么,关于 UDP 协议还有什么要说的吗?
没有了。UDP 是一个简单的协议。
下一课,我们将学习比 UDP 更可靠的 TCP 协议。
一起加油吧~
}如果您想了解更多技术资源,欢迎加入点击这里钉钉群交流IT技术资源查看"IT技术交流群一"群的钉钉群号: 129605002953