一文读懂UDP协议

2023-05-15 10:40:26 digiproto

UDP(User Datagram Protocol) 用户数据报协议


什么是UDP

数据分发服务(DDS™)是一个简单的面向数据报的通信协议,位于OSI模型的传输层。该协议在RFC 768中被规范。典型网络上的众多使用UDP协议的关键应用在一定程度上是相似的。


使用UDP的优势

相比于TCP 协议,UDP具有更低的消耗和延迟优势,适用于不需要或在程序中执行错误检查和纠正的应用,它避免了协议栈中此类处理的开销。因为在特定场景里丢弃数据包比等待或重传导致延迟更可取。


使用UDP的劣势

由于UDP缺乏可靠性且属于无连接协议,所以应用程序通常必须容许一些丢失、错误或重复的数据包。某些应用程序(如TFTP)可能会根据需要在应用程序层中添加基本的可靠性机制。


应用场景

许多关键的互联网应用程序使用UDP,包括:

域名系统(DNS),其中查询阶段必须快速,并且只包含单个请求,后跟单个回复数据包:


1.动态主机配置协议(DHCP),用于动态分配IP地址;

2.简单网络管理协议(SNMP)

3.路由信息协议(RIP)

4.网络时间协议(NTP)


流媒体、在线游戏流量通常使用UDP传输。 实时视频流和音频流应用是可以接受偶尔的丢包,不能接受重传数据包带来的高延迟。


UDP的分组结构

image.png


UDP报头

报头包括4个字段,每个字段占用2个字节(即16个二进制位)。在IPv4中,“来源连接端口”和“校验和”是可选字段(以粉色背景标出)。在IPv6中,只有来源连接端口是可选字段。 各16bit的来源端口和目的端口用来标记发送和接受的应用进程。因为UDP不需要应答,所以来源端口是可选的,如果来源端口不用,那么置为零。在目的端口后面是长度固定的以字节为单位的长度域,用来指定UDP数据报包括数据部分的长度,长度最小值为8byte。首部剩下的16bit是用来对首部和数据部分一起做校验和(Checksum)的。这部分是可选的,但在实际应用中一般都使用这一功能。


校验和

校验和字段可以用于发现头部信息和数据中的传输错误。该字段在IPv4中是可选的,在IPv6中则是强制的。如果不使用校验和,该字段应被填充为全0。


Java使用UDP协议简单例子

发送端代码:

public class DaytimeUDPClient {
   private final static int PORT = 13;
   public static void main(String[] args) {
       //传入0表示让操作系统分配一个端口号
       try (DatagramSocket socket = new DatagramSocket(0)) {
           socket.setSoTimeout(10000);
           //指定包要发送的目的地
           DatagramPacket request = new DatagramPacket(“127.0.0.1”, 1, host, PORT);
           //为接受的数据包创建空间
           DatagramPacket response = new DatagramPacket(new byte[1024], 1024);
           socket.send(request);
           socket.receive(response);
           String result = new String(response.getData(), 0, response.getLength(), "ASCII");
           System.out.println(result);
       } catch (IOException e) {
           e.printStackTrace();
       }
   }
}


接收端代码:

public class DaytimeUDPServer {
   private final static int PORT = 13;
   public static void main(String[] args) {
       try (DatagramSocket socket = new DatagramSocket(PORT)) {
           while (true) {
               try {
                   DatagramPacket request = new DatagramPacket(new byte[1024], 1024);
                   socket.receive(request);

                   String daytime = new Date().toString();
                   byte[] data = daytime.getBytes("ASCII");
                   DatagramPacket response = new DatagramPacket(data, data.length, request.getAddress(), request.getPort());
                   socket.send(response);
                   System.out.println(daytime + " " + request.getAddress());
               } catch (IOException e) {
                   e.printStackTrace();
               }
           }
       } catch (IOException e) {
           e.printStackTrace();
       }
   }
}



SkyEye天目全数字实时仿真软件


在复杂嵌入式系统中通常依据数据传输距离远近、数据量大小、实时性、连接端口数量等要求,选择不同网络进行数据通讯。最常用的网络总线接口,如TCP、CAN总线等。由本公司自主研发的SkyEye全数字实时仿真软件是基于可视化建模的硬件行为级仿真平台,利用拖拽的方式快速搭建任意的虚拟硬件平台,保证虚拟嵌入式系统的可靠性和实时性 ,目前已支持 CAN总线、1553B总线等多种通信总线。开发者可以通过SkyEye在嵌入式硬件平台上模拟网络通信代码。SkyEye目前可以运行主流的操作系统,还能适配国内自主研发的操作系统天脉。

图片关键词


首页
产品
新闻
联系