UDP 协议解析 - 1

目录

  • 1. 概述
  • 2. UDP 的主要特点
  • 3. UDP 的首部格式
  • 3. UDP 校验和
    • 3.1 伪首部
    • 3.2 UDP 校验和计算方法
  • [参考文献]

1. 概述

用户数据报协议(UDP,User Datagram Protocol)为应用程序提供了一种无需建立连接就可以发送封装的 IP 数据报的方法。UDP是一种保留消息边界的简单的面向数据报的协议。UDP不提供差错纠正、队列管理、重复消除、流量控制和拥塞控制,但提供差错检测(包含我们在传输层中碰到的第一个真实的端到端(end-to-end)校验和)。这种协议自身提供最小功能,因此使用它的应用程序要做许多关于数据报如何发送和处理的控制工作。想要保证数据被可靠传递或正确排序,应用程序必须自己实现这些保护功能。一般来说,每个被应用程序请求的UDP输出操作只产生一个UDP数据报,从而发送一个IP数据报。而对于面向数据流的传输层协议(例如TCP),应用程序写入的全部数据与真正在单个IP数据报里传送的或接收方接收的内容可能没有联系。

2. UDP 的主要特点

1). UDP 是无连接的,即发送数据之前不需要建立连接,因此减少了开销和发送数据之前的时延。
2). UDP 使用尽最大努力交付,即不保证可靠交付,因此主机不需要维持复杂的连接状态表。
3). UDP 是面向报文的。发送方的UDP对应用程序交下来的报文,在添加首部后就向下交付IP层。UDP对应用层交下来的报文,既不合并,也不拆分,而是保留这些报文的边界。因此,应用程序必须选择合适大小的报文。
4). UDP 没有拥塞控制,因此网络出现的拥塞不会使源主机的发送速率降低。很多的实时应用(如IP电话、实时视频会议等)要去源主机以恒定的速率发送数据,并且允许在网络发生拥塞时丢失一些数据,但却不允许数据有太多的时延。UDP正好符合这种要求。
5). UDP 支持一对一、一对多、多对一和多对多的交互通信
6). UDP 的首部开销小,只有8个字节,比TCP的20个字节的首部要短。

虽然某些实时应用需要使用没有拥塞控制的UDP,但当很多的源主机同时都向网络发送高速率的实时视频流时,网络就有可能发生拥塞,结果大家都无法正常接收。因此,不使用拥塞控制功能的UDP有可能会引起网络产生严重的拥塞问题。
还有一些使用UDP的实时应用,需要对UDP的不可靠的传输进行适当的改进,以减少数据的丢失。在这种情况下,应用进程本身可以在不影响应用的实时性的前提下,增加些提高可靠性的措施,如采用前向纠错重传已丢失的报文

3. UDP 的首部格式

UDP有两个字段:数据字段和首部字段。首部字段很简单,只有8个字节,由4个字段组成,每个字段的长度都是两个字节。各字段意义如下:

  1. 源端口:源端口号。在需要对方回信时选用。不需要时可用全0。
  2. 目的端口:目的端口号。这在终点交付报文时必须要使用到。
  3. 长度: UDP用户数据报的长度,其最小值是8(仅有首部),发送一个带0字节数据的UDP数据报是允许的。值得注意的是,UDP长度字段是冗余的;IPV4头部包含了数据报的总长度,同时IPV6头部包含了负载长度。因此,一个UDP/IPV4数据报的长度等于IPV4数据报的总长度减去IPV4头部的长度。一个UDP/IPV6数据报的长度等于包含在IPV6头部中的负载长度(payload length)字段的值减去所有扩展头部(除非使用了超长数据报)的长度。这两种情况下,UDP长度字段应该与从IP层提供的信息计算得到的长度是一致的。
  4. 校验和:检测UDP用户数据报在传输中是否有错。有错就丢弃。

当运输层从 IP 层收到 UDP 数据报时,根据目的端口,通过相应的端口上交给应用进程。

如果接收方 UDP发现报文中的目的端口号不正确(即不存在对应于该端口号的应用进程),就丢弃该报文,并由网际控制报文协议 ICMP 发送“端口不可达”差错报文给发送方。
请注意,虽然在 UDP 之间的通信要用到其端口号,但由于 UDP 的通信是无连接的,因此不需要使用套接字(TCP 之间的通信必须要在两个套接字之间建立连接)。

3. UDP 校验和

UDP 校验和是一个端到端的传输层校验和,是对包含了IP头部中的源(Source)和目的IP地址(Destination Address)字段的 UDP 伪首部计算得到的。它由初始的发送方计算得到,由最终的目的方校验。它在传输中不会被修改(除非它通过一个NAT)。IPV4 头部中的校验和只覆盖整个头部(即它不覆盖IP分组中的任何数据),它在每个IP跳都要被重新计算(因为IPV4 TTL字段的值在数据报转发时会被路由器减少)。传输协议(如 TCP、UDP)使用校验和来覆盖它们的头部和数据。对于 UDP 来说,校验和是可选的,而其他的则是强制的。当 UDP 在IPV6中使用时,校验和的计算与使用是强制的,因为在IP层没有头部校验和。为了给应用程序提供无差错数据,像UDP这样的传输层协议,在投递数据到接收方应用程序之前,必须计算校验和或者使用其他差错监测机制。

3.1 伪首部

在UDP伪首部中,包含32位源IP地址,32位目的IP地址,8位填充0,8位协议,16位UDP长度。伪首部并非TCP&UDP数据报中实际的有效成分。伪首部是一个虚拟的数据结构,其中的信息是从数据报所在IP分组头的分组头中提取的,既不向下传送也不向上递交,而仅仅是为计算校验和。
伪头部的目的是让UDP层验证数据是否已经到达正确的目的地(即,该IP没有接受地址错误的数据报,也没有给UDP一个本该其他传输协议的数据报),计算UDP校验和时覆盖的字段,包含了伪头部以及UDP头部和负载。

3.2 UDP 校验和计算方法

UDP计算校验和的方法和计算IP数据报首部校验和的方法相似。但不同的是:IP数据报的校验和只检验IP数据报的首部,但UDP的校验和是将首部和数据部分一起都检验
在发送方,首先是将全零放入检验和字段。再将伪首部以及UDP用户数据报看是由许多16位的字串接起来。若UDP用户数据报的数据部分不是偶数个字节,则要填入一个全零字节(最后一个奇数字节应是16位数的高字节而低字节填0,此字节不发送)。 然后按二进制反码计算出这些16位字的和。 将此和的二进制反码写入校验和字段后,发送此UDP用户数据报。
在接收方,把收到的UDP用户数据报连同伪首部(以及可能的填充全零字节)一起,按二进制反码求这些16位字的和。当无差错时其结果应全为1。否则就表明有差错出现,接收方就丢弃此UDP用户数据报(也可以上交给应用层,但附上出现了差错的警告)。如果校验和字段值为0x0000表示发送方没有计算校验和。

如上图所示,伪首部的第3字段是全零;第4字段是IP首部中的协议字段的值。对于UDP,此协议字段值为17;第5字段是UDP用户数据报的长度。因此,这样的检验和,既检查了UDP用户数据报的源端口和目的端口以及UDP用户数据报的数据部分,又检查了IP数据报的源IP地址和目的地址。注意,UDP数据报的长度在校验和的计算中出现了两次。

计算原理是二进制反码求和运算,具体来说就是:

0 + 0 = 0
1 + 0 = 0 + 1 = 1
1 + 1 = 10

如果最高位有进位,就把进位的1取下来与最低位再做一次二进制加法
示例:

图3-2-1 中二进制反码求和的参考代码:

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int MAX_NUM = 65536; // 2^16 = 1 0000 0000 0000 0000
int a[15] = {153*256+19,8*256+104,171*256+3,14*256+11,17,15,1087,13,15,21573,21332,18766,18176};
// 256 = 2^8 = 1 0000 0000
int main()
{
    int sum = 0;
    for(int i=0;i<13;i++){
        sum += a[i];
        if(sum > MAX_NUM){
            sum = sum % MAX_NUM + 1;
        }
    }
    printf("%d\n",sum);

    return 0;
}

注意:UDP协议(传输层)直接操作IP(网络层)的比特,会导致所谓的“违反分层”(layering violation)规则。但这只对协议实现产生微小的影响,因为一般来说,当数据传递到(或来自于)UDP时,IP层的信息已经是现成的了。相比之下,更应该关注NAT,特别是当UDP数据报被分片时。

尽管UDP数据报校验和在原始UDP规范中是可选的,目前它们还是被要求在主机中默认使用[RFC1122]。在20世纪80年代,一些计算机供应商默认关闭了UDP校验和功能以加速其Sun网络文件系统(NFS)的实现,该网络文件系统使用了UDP。因为有第2层的CRC保护(这要比互联网校验和更强壮),在许多情况下这可能不会产生问题,然而默认关闭校验和功能被认为是一种不好的方法(也是违反RFC规范的)。早期的互联网经验表明,当数据报通过路由器时,总会存在有软件和硬件漏洞的路由器在转发数据报时会修改其中的比特。如果端到端的UDP校验和被关闭的话,这些UDP数据报中的错误就无法检测到。同时注意到一些更老的数据链路协议(比如,串行线IP或SLIP)没有任何形式的数据链路校验和,因此存在IP分组被修改而检测不到的可能性,除非引入另一种校验和。
考虑到伪头部这样的结构,可以很清楚地看到,当一个UDP/IPv4数据报穿过一个NAT时,不仅IP层头部的校验和要被修改,而且UDP伪头部的校验和也必须被正确地修改,因为IP层的地址和/或UDP层的端日号可能会改变。因此NAT通常因同时修玫分组中协议的多层而违反分层规则。当然,考虑到伪头部本身就是违反分层规则的, NAT没有选择。UDP流量被NAT处理时的一些特定规则由[RFC4784]给出。

[参考文献]

  1. 《TCP/IP 详解卷1:第2版》
  2. 《计算机网络》 谢希仁.
  3. 百度百科 伪头部
  4. IP,UDP,TCP校验和有什么区别 http://www.lianhekj.com/question/328086705.html
  5. 二进制反码求和运算 https://www.cnblogs.com/jcchan/p/10400504.html
  6. UDP检验和中的二进制反码运算 https://blog.csdn.net/weixin_43790264/article/details/92847622

原文地址:https://www.cnblogs.com/sxiszero/p/11565108.html

时间: 2024-10-10 10:34:15

UDP 协议解析 - 1的相关文章

UDP协议疑难杂症全景解析

转载:http://blog.csdn.net/dog250/article/details/6896949 UDP协议疑难杂症全景解析 2011-10-22 19:26 2989人阅读 评论(4) 收藏 举报 tcp网络算法交通socket通讯 如今,但凡说精通网络的,第二个意思就是"精通TCP",事实上,很多自称精通TCP的家伙们只是精通socket接口而已,对TCP行为精通的并不多,笔者也不算精通,但绝对是中等以上水平.如果你真的精通TCP行为,那么本文不读也罢,直接发邮件给我,

JavaSE——UDP协议网络编程(二)

在 UDP 网络编程中,发送方与接收方没有建立联系,没有明显的服务器端和客户端的区别. 类 DatagramSocket: 此类表示用来发送和接收数据报包的套接字. 主要的构造方法: DatagramSocket():创建实例,绑定本机的默认IP地址,随机选择端口.通常用于客户端编程,没有特定监听的端口,仅仅使用一个临时的.  DatagramSocket(int port):创建实例,指定端口号,即固定监听Port端口的报文.  DatagramSocket(int port, InetAdd

java基础知识回顾之java Socket学习(一)--UDP协议编程

UDP传输:面向无连接的协议,不可靠,只是把应用程序传给IP层的数据报包发送出去,不保证发送出去的数据报包能到达目的地.不用再客户端和服务器端建立连接,没有超时重发等机制,传输速度快是它的优点.就像寄信,写好信放到邮箱桶里面,既不能保证信件在邮递过程中不丢失,也不能保证信件是按顺序寄到目的地的. 看java API用到java.net.DatagramSocket和java.net.DatagramPacket类: DatagramSocket:此类表示用来发送和接收数据报包的套接字(IP地址和

SOCKS5 协议解析

意图 SOCKS5 是一个代理协议,旨在为位于 Intranet 防火墙后的用户提供访问 Internet 的代理服务(Intranet,你没听错,这是个有一定年头的协议,其 RFC 提案的时间比 HTTP 1.0 还要早两个月). 代理 根据 HTTP 1.1 的定义,proxy 是: An intermediary program which acts as both a server and a client for the purpose of making requests on be

java 25 - 4 网络编程之 UDP协议传输的代码优化

UDP协议的输出端: 1 /* 2 UDP发送数据: 3 A:创建Socket发送端对象 4 B:创建数据报包(把数据打包) 5 C:调用Socket对象发送数据报包 6 D:释放资源(底层是IO流) 7 */ 8 public class NewSend { 9 10 public static void main(String[] args) throws IOException { 11 12 // A:创建Socket发送端对象 13 DatagramSocket ds = new Da

java 25 - 4 网络编程之 UDP协议传输思路

UDP传输 两个类:DatagramSocket与DatagramPacket(具体看API) A:建立发送端,接收端. B:建立数据包. C:调用Socket的发送接收方法. D:关闭Socket. E:发送端与接收端是两个独立的运行程序. UDP传输-发送端思路 UDP发送数据: A:创建Socket发送端对象 B:创建数据报包(把数据打包) C:调用Socket对象发送数据报包 D:释放资源(底层是IO流) UDP传输-发送端代码 1 public static void main(Str

通用轻量级二进制格式协议解析器

在通信协议中,经常碰到使用私有协议的场景,报文内容是肉眼无法直接看明白的二进制格式.由于协议的私有性质,即使大名鼎鼎的 Wireshark,要解析其内容,也无能为力. 面对这种情况,开发人员通常有两个办法:第一,对照报文内容和协议规范进行人工分析(假设内容没有经过加密.压缩):第二,编程实现协议报文的解析(源于程序员的懒惰 ^_^). 很明显,第二条道路是主流.目前比较常见的实现方式是开发对应的 Wireshark 插件,包括 C.Lua 等插件.当然,插件完成后需要运行 Wireshark 才

STUN和TURN协议解析

在现实Internet网络环境中,大多数计算机主机都位于防火墙或NAT之后,只有少部分主机能够直接接入Internet.很多时候,我们希望网络中的两台主机能够直接进行通信,即所谓的P2P通信,而不需要其他公共服务器的中转.由于主机可能位于防火墙或NAT之后,在进行P2P通信之前,我们需要进行检测以确认它们之间能否进行P2P通信以及如何通信.这种技术通常称为NAT穿透(NAT Traversal).最常见的NAT穿透是基于UDP的技术,如RFC3489中定义的STUN协议. STUN,首先在RFC

视音频数据处理入门:UDP-RTP协议解析

===================================================== 视音频数据处理入门系列文章: 视音频数据处理入门:RGB.YUV像素数据处理 视音频数据处理入门:PCM音频采样数据处理 视音频数据处理入门:H.264视频码流解析 视音频数据处理入门:AAC音频码流解析 视音频数据处理入门:FLV封装格式解析 视音频数据处理入门:UDP-RTP协议解析 ===================================================