UDP协议的特点与原理
用户数据报协议(User Datagram Protocol,UDP)是当今互联网传输层的两个主要协议之一,与另一个协议(传输控制协议,TCP)互为补充。其地位十分重要,值得在此介绍。
[RFC0768]是UDP协议的正式规范,它至今仍然是一个标准,30多年来没有做过重大的修改。
对于RFC,感兴趣的大家可以上网查一下,它的全称是“Request For Comments”,即“请求评论”。包含了几乎所有重要的Internet文字资料。一个RFC出版后永远不会被修改或取消,而只有可能被新的RFC取代。这里说UDP“至今仍然是一个标准”,也就是说它从出现至今从未被更新过,可见其设计的简洁与高明。
撰写本文主要想通过介绍UDP协议的特点与原理,看透UDP协议设计背后的思想,深度理解通信、端口和连接等概念。
UDP协议的特点
所谓特点,即与其他协议的不同之处。如前所述,能与UDP比较的协议非TCP莫属,故下文会反复提到TCP协议,如果你没听说过TCP,问题也不大,我会尽量详细介绍其中各个概念。
总而言之,UDP有如下几个特点:
- 无连接
- 不可靠
- 不提供差错纠正、队列管理、重复消除、流量控制和拥塞控制
- 保留消息边界
- 开销小、效率高
那么相对应的,TCP的特点如下:
- 有连接
- 可靠
- 不保留消息边界
- 开销比UDP大
那么一目了然,UDP的特点反过来就是TCP的特点,反之亦然。那么到底什么是无连接?什么不可靠?什么是消息边界呢?别急,我马上就讲~
什么叫无连接?
graph LR
subgraph Sender
Sender_IP[192.168.1.101]
end
subgraph Receiver
Receiver_IP[192.168.1.102]
end
Sender_IP --> Receiver_IP
我们知道,UDP是一个传输层的协议,它工作在网络层之上,具体来说,工作在IP协议之上。位于网络层的IP协议为我们实现了将数据从网络上一个IP主机发送到另一个主机的功能。而一台主机上可能有多个程序需要同时和其他主机上的程序通信,这个问题则直接砸到了传输层协议的脑袋上。
由于当今互联网几乎全部使用的都是TCP/IP协议,所以当我提到”网络层协议“时,毫无疑问指的就是IP协议或它的升级版ICMP协议;当我提到”传输层协议“时,想介绍的则是UDP协议和TCP协议共通之处。
传输层协议引入一个“端口”的概念用于解决上述问题,每个传输层数据包都会指定要发往哪个“端口”,而对应的应用程序只需预先绑定这个端口,就能正确收到发给它的数据。
graph LR
subgraph Sender
Sender_Port1[Port: 10086]
Sender_Port2[Port: 10087]
Sender_IP[192.168.1.101]
end
subgraph Receiver
Receiver_Port1[Port: 10000]
Receiver_Port2[Port: 10001]
Receiver_IP[192.168.1.102]
end
Sender_Port1 --> Receiver_Port1
Sender_Port2 --> Receiver_Port2
端口一般是一个16位正整数,所以范围一般是0到65535。
不可靠
UDP协议不提供重复消除
说UDP协议不可靠,是因为当你使用它发送数据时,并不能保证你的数据真的能被送到目标机器的目的端口,而是有可能发生丢失或重复。是的,不仅有可能丢失,还有可能重复(即被收到多次)。
反过来也可以说,TCP协议保证你发送的数据会被并且仅仅会被接收到一次。
UDP协议不提供队列管理
何为队列管理?这里的队列管理指的是是否保证消息的顺序。
假设你打算用发送5个数据包,他们大小不一,我们依发送次序给它们编号:
0 | 1 | 2 | 3 | 4 |
---|---|---|---|---|
事证实明 | 文字的 | 序顺 | 并不响影 | 读阅 |
如果你用UDP协议发送它们,那么接收方接收时的情形会是如何呢?最好的情况下当然是按照原样收到,但也完全可能出现如下情况:
2 | 1 | 0 | 4 | 3 |
---|---|---|---|---|
序顺 | 文字的 | 事证实明 | 读阅 | 并不响影 |
可以看到各个数据包之间的顺序被打乱了,但是单个数据包并没有发生改变。什么是单个数据包没有发生改变?请听下节分解……
保留消息边界
前面说到,UDP的特点是虽然不能保证数据们按照它们被发送的顺序被依次收到,但是可以保证消息的边界不发生改变。为了说明什么是消息边界发生改变,接下来给出一个TCP的例子:
0 | 1 | 2 | 3 | |
---|---|---|---|---|
事证实 | 明文 | 字的序顺并不 | 响影读阅 |
可以观察到在TCP中,顺序得到了保证,但是数据包的边界发生了改变。事实上,当你在接收TCP数据时,消息边界完全可以由你自己决定:先读三个字,读到的就是“事证实”,再读四个字,读到的就是“明文字的”。
老师上课举的一个例子非常形象,传输数据就像是运输石油,UDP就相当于用油罐车运输,TCP则相当于管道运输。 如果你用五辆油罐车运输五车石油,最先到的油罐车不一定就是最先出发的那辆,但是每辆车内的石油之间是严格分界的; 如果用管道运输这五份石油,最先进入管道的石油必定最先从出口出来,但是每份石油之间的边界并不存在。
UDP协议原理
数据包格式
0 7 8 15 16 23 24 31
+--------+--------+--------+--------+
| Source | Destination |
| Port | Port |
+--------+--------+--------+--------+
| | |
| Length | Checksum |
+--------+--------+--------+--------+
|
| data octets ...
+---------------- ...
User Datagram Header Format
0 7 8 15 16 23 24 31
+--------+--------+--------+--------+
| source address |
+--------+--------+--------+--------+
| destination address |
+--------+--------+--------+--------+
| zero |protocol| UDP length |
+--------+--------+--------+--------+
Pseudo Header
我能发送无限长的数据吗?
不能,懒得算最大报文长度了,读者自己算下吧。
什么是端口号?
此处想解释tcp的端口跟udp端口的关系,它们会冲突吗?如果udp把端口号定义为32字节,tcp会受到影响吗?
重新理解“连接”
这里想解释连接的概念,udp协议定义的源端口号和目的端口号能否看成一个最原始的连接呢?
总结
咕?