TCP/IP详解notes:03UDP
1. UDP 简要介绍
UDP:User Datagram Protocol 用户数据报协议.
- 无连接,不可靠
- 无连接:意思就是在通讯之前不需要建立连接,直接传输数据.
- 不可靠:是将数据报的分组从一台主机发送到另一台主机,但并不保证数据报能够到达另一端, 任何必须的可靠性都由应用程序提供.
在 UDP 情况下,虽然可以确保发送消息的大小,却不能保证消息一定会达到目的端. 没有超时和重传功能,当 UDP 数据封装到 IP 数据报传输时,如果丢失,会发送一个 ICMP 差错报文给源主机. 即使出现网络阻塞情况,UDP 也无法进行流量控制. 此外,传输途中即使出现丢包,UDP 也不负责重发,甚至当出现包的到达顺序杂乱也没有纠正的功能
UDP封装
UDP首部
UDP检验和计算过程中使用的各个字段
2. UDP 协议头
2.1 UDP 端口号
由于很多软件需要用到 UDP 协议.端口号的功能
: 通过某个标志用以区分不同的程序所需要的数据包
.
例如某一个 UDP 程序 A 在系统中注册了3000端口,那么,以后从外面传进来的目的端口号为3000的 UDP 包都会交给该程序.端口号理论上可以有2^16
这么多.因为它的长度是16bit
.
2.2 UDP 检验和
这是一个可选的选项,并不是所有的系统都对 UDP 数据包加以检验和数据
(相对 TCP 协议的必须来说),但是 RFC 中标准要求, 发送端应该计算检验和
.
UDP 检验和覆盖 UDP 协议头和数据
,这和 IP 的检验和是不同的,IP 协议的检验和只是覆盖 IP 数据头,并不覆盖所有的数据
.
UDP 和 TCP 都包含 一个伪首部,这是为了计算检验和而摄制的.伪首部甚至还包含 IP 地址这样的 IP 协议里面都有的信息,目的是 让 UDP 两次检查数据是否已经正确到达目的地.
如果发送端没有打开检验和选项,而接收端计算检验和有差错,那么 UDP 数据将会 被悄悄的丢掉(不保证送达),而不产生任何差错报文.
2.3 UDP 长度
UDP 可以很长很长,可以有65535字节那么长.但是一般网络在传送的时候,一次一般传送不了那么长的协议(涉及到 MTU 的问题),就只好对数据分片
,当然,这些是对 UDP 等上级协议透明的,
UDP 不需要关心 IP 协议层对数据如何分片,下一个章节将会稍 微讨论一些分片的策略.
3. IP 分片
IP在从上层接到数据以后,要根据IP地址来判断从那个接口发送数据(通过选路),并进行MTU的查询,如果数据大小超过MTU 就进行数据分片. 数据的分片是对上层和下层透明,而数据也只是到达目的地还会被重新组装,不过不用担心,IP 层提供了足够的信 息进行数据的再组装.
在 IP 头里面,16bit
识别号唯一记录了一个 IP 包的 ID,具有同一个 ID 的 IP 片将会被重新组装;
而13位片偏移则记录了某 IP 片相对整个包的位置;而这两个表示中间的3bit 标志则标示着该分片后面是否还有新的分片.
这三个标示就组成了 IP分片的所有信息,接受方就可以利用这些信息对 IP 数据 进行重新组织(就算是后面的分片比前面的分片先到,这些信息也是足够了).
因为分片技术在网络上被经常的使用,所以伪造 IP 分片包进行流氓攻击
的软件和人也就层出不穷.可以用 Trancdroute 程序来进行简单的 MTU 侦测.
4. UDP 和 ARP 之间的交互式用
这是不常被人注意到的一个细节,这是针对一些系统地实现来说的.当 ARP 缓存还是空的时候.UDP 在被发送之前一定要发送一个 ARP 请求来获得目的主机的 MAC 地址
,
如果这个 UDP 的数据包足够大,大到 IP 层一定要对其进行分片的时候,想象中,该 UDP 数据包的第一个分片会发出一个 ARP 查询请求, 所有的分片都会等到这个查询完成以后再发送.事实上是这样吗?
结果是,某些系统会让每一个分片都发送一个 ARP 查询,所有的分片都在等待
,但是接受到第一个回应的时候,主机却只发送了最后一个数据片而抛弃了其他,这实在是让人匪夷所思.
这样,因为分片的数据不能被及时组装,接受主机将会在一段时间内将永远 无法组装的 IP 数据包抛弃,
并且发送组装超时的 ICMP 报文(其实很多系统不产生这个差错),以保证接受主机自己的接收端缓存不 被那些永远得不到组装的分片满.
5. ICMP 源站抑制差错
当目标主机的处理速度赶不上数据接收的速度,因为接受主机的 IP 层缓存会被占满,所以主机就会发出一个“我受不了”的一个 ICMP 报文.
6. UDP 服务器设计
UDP 协议的某些特性将会影响我们的服务器程序设计,大致总结如下:
- 关于客户IP和地址:服务器必须有根据客户IP地址和端口号判断数据包是否合法的能力(这似乎要求每一个服务器都要具备)
- 关于目的地址:服务器必须要有过滤广播地址的能力.
- 关于数据输入:通常服务器系统的每一个端口号都会和一块输入缓冲区对应,进来的输入根据先来后到的原则等待服务器的处理,所以难免会出现缓冲区溢出的问题,这种情况下,UDP 数据包可能会被丢弃,而应用服务器程序本身并不知道这个问题.
- 服务器应该限制本地IP地址,就是说它应该可以把自己绑定到某一个网络接口的某一个端口上.