UDP协议详解+代码演示

[复制链接]
发表于 2025-9-22 05:08:31 | 显示全部楼层 |阅读模式
1、UDP协议根本

1. UDP是什么?

UDP(User Datagram Protocol,用户数据报协议)是传输层的焦点协议之一,与TCP并列。它的主要特点是:​​​​

  •         无毗连:通讯前不须要创建毗连(知道对端的IP和端标语就直接进行传输,不须要创建毗连)
  •         不可靠:不包管数据包的次序、完备性或可达性(没有确认机制,没有重传机制;假如由于网络故障该段无法发到对方,UDP协议层也不会给应用层返回任何错误信息)
  •         巨细受限:⼀次最多传输64k(UDP协议首部中有⼀个16位的最大长度.也就是说⼀个UDP能传输的数据最大长度是 64K(包罗UDP首部))
  •         轻量级:头部开销小(仅8字节)
  •         高效:没有TCP的握手、确认和重传机制
2. UDP报文布局

UDP数据包(称为数据报)由头部和数据部分构成:


  •         源端标语(2字节):发送方端口
  •         目的端标语(2字节):吸收方端口
  •         数据报长度(2字节):头部+数据的长度
  •         校验和(2字节):错误检测(可选)假如校验和堕落则直接抛弃
2、UDP的焦点特性

1. 无毗连通讯:UDP不须要预先创建毗连,直接发送数据报。这雷同于寄信,不须要确认收件人是否在家。
2. 不可靠传输:UDP不提供:数据包确认机制、丢失重传机制、数据包排序功能
3.面向数据报:每个UDP数据报都是独立的,这与TCP的字节流模式差别
4.支持广播和多播:UDP可以向多个主机同时发送数据:

  •         单播 :一对一
  •         广播 :一对全部
  •         多播 :一对一组
3、基于UDP的应用层协议


  • NFS:网络文件系统
  • TFTP:简朴文件传输协议
  • DHCP:动态主机设置协议
  • BOOTP:启动协议(用于无盘装备启动)
  • DNS:域名剖析协议
当然,也包罗我们自己写UDP步调时自界说的应用层协议。
4、Java中的UDP编程

主要使用了两个类 :
1、DatagramSocket :用于发送和吸收数据报的套接字
// 创建UDP套接字(绑定随机端口)
DatagramSocket socket = new DatagramSocket();
// 创建绑定特定端口的套接字
DatagramSocket serverSocket = new DatagramSocket(8080);
2、DatagramPacket :体现UDP数据报的容器
// 创建吸收数据包
byte[] buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
// 创建发送数据包
String message = "Hello UDP";
byte[] data = message.getBytes();
DatagramPacket sendPacket = new DatagramPacket(
    data, 
    data.length, 
    InetAddress.getByName("localhost"), 
    8080
);
5、完备Java UDP示例

1.Echoserver:UDP服务器,吸收客户端消息并原样返回
  1. package Network.UDP;
  2. import java.io.IOException;
  3. import java.net.DatagramPacket;
  4. import java.net.DatagramSocket;
  5. import java.net.SocketException;
  6. public class Echoserver {
  7.     //创建一个socket对象
  8.     private DatagramSocket socket;
  9.     //构造方法,初始化socket对象
  10.     public Echoserver(int port) throws SocketException {
  11.         socket = new DatagramSocket(port);
  12.     }
  13.     //启动服务器,完成主要的业务逻辑
  14.     public void start() throws IOException {
  15.         System.out.println("服务器启动!");
  16.         while(true) {
  17.             //1.接收客户端的请求并解析
  18.             //1)创建一个字节数组(DatagramPacket 对象),用于存储接收到的数据
  19.             DatagramPacket reqPacket = new DatagramPacket(new byte[4096],4096);
  20.             //2)通过receive读取网卡的数据,如果网卡没有收到数据,就会阻塞等待
  21.             socket.receive(reqPacket);
  22.             //3)把DATagramPacket中的数据解析成字符串,只需要从DatagramPacket取到有效的树即可
  23.             String request = new String(reqPacket.getData(),0,reqPacket.getLength());
  24.             //2.根据请求计算响应
  25.             String response = process(request);
  26.             //3.把响应写回客户端
  27.             //1)把响应字符串转成字节数组,并封装成DatagramPacket对象
  28.             DatagramPacket resPacket = new DatagramPacket(response.getBytes(),response.getBytes().length,
  29.                     reqPacket.getSocketAddress());
  30.             //2)通过socket把DatagramPacket对象发送出去 (把DatagramPacket写回到客户端)
  31.             socket.send(resPacket);
  32.             //4.打印日志日志
  33.             System.out.printf("[%s:%d] req: %s,resp: %s\n",
  34.                     reqPacket.getAddress(),reqPacket.getPort(),request,response);
  35.         }
  36.     }
  37.     //由于是“回显服务器”,所以响应和请求是一样的,直接返回请求即可
  38.     public String process(String request) {
  39.         return request;
  40.     }
  41.     public static void main(String[] args) throws IOException {
  42.         Echoserver server = new Echoserver(9090);
  43.         server.start();          //回显服务器完成
  44.     }
  45. }
复制代码
代码具体剖析:
①创建 EchoServer 服务端的类,界说成员变量

  •         DatagramSocket:UDP通讯的焦点类,用于发送和吸收数据报
  •         封装在类中作为成员变量,整个生命周期内有用


②构造方法

  •         创建绑定到指定端口的 DatagramSocket(可能会抛出异常,如:该端口已被占用)
  •         port 是服务器自身绑定的监听端标语,等待客户端发送数据,客户端须要知道服务器的这个端标语才气向其发送消息。


  •         客户端通过该端口找到服务器,而客户端的端口由系统动态分配。
  •         这种计划体现了 UDP 无毗连的特性,服务器只需关注自身绑定端口即可吸收全部客户端消息。


③焦点业务逻辑(start方法)

  • while 无穷循环吸收来自客户端的数据,这里可以根据自己的需求更改吸收次数
  • 创建缓冲区:分配一个4096字节(字节巨细自行界说不溢出就行)的空数组,存储吸收到的数据
  • 壅闭等待数据报到达(数据此时已存入 reqPacket 的字节数组中)假如 reqPacket 没有吸收到客户端发来的数据这里会壅闭等待
  • 声明 String 范例的 request 变量,将 reqPacket 中的数据剖析为字符串

  • getData() :获取字节数组(可能包罗多余的空字节)
  • getLength() :获取实际有用数据长度(制止剖析无效字节)
在网络编程中,将相应(response)转成字节数组(byte[])再发送是须要的步调,这与盘算机底层的数据传输机制和网络协议的特性密切干系。

  • process() :返回相应后的数据,由于整段代码实现的是 Echo(回显) 服务器代码,相应内容=哀求内容,所以方法中直接返回哀求即可
  • soclet.send() :将数据发送回客户端
附上发送回客户端的终端代码


  • 打印日志日志:打印客户端信息和通讯内容



④主方法

  •         new Echoserver(9090) :调用构造函数,创建绑定到 9090 端口的 DatagramSocket(UDP套接字)
  •         server.start() :启动服务器循环,等待客户端数据报



2.EchoClient:UDP客户端,发送消息并显示服务器返回的相应
  1. package Network.UDP;
  2. import java.io.IOException;
  3. import java.net.DatagramPacket;
  4. import java.net.DatagramSocket;
  5. import java.net.InetAddress;
  6. import java.util.Scanner;
  7. public class EchoClient {
  8.     private DatagramSocket socket = null;
  9.     private String serverIp;
  10.     private int serverPort;
  11.     public EchoClient(String serverIp, int serverPort) throws IOException {  
  12.         socket = new DatagramSocket();
  13.         this.serverIp = serverIp;
  14.         this.serverPort = serverPort;
  15.     }   
  16.     //启动客户端,发送数据,接收数据,关闭连接
  17.     public void start() throws IOException {
  18.         Scanner scanner = new Scanner(System.in);
  19.         System.out.println("客户端启动!");
  20.         while(true) {
  21.             //1.从控制台读取要发送的数据内容(用字符串表示)
  22.             System.out.print(">");
  23.             String request = scanner.nextLine();
  24.             //2.构造成UDP请求,并发送.不光要填内容,还要填服务器的地址和端口号
  25.             DatagramPacket reqPacket = new DatagramPacket(request.getBytes(),request.getBytes().length,
  26.                                             InetAddress.getByName(serverIp),serverPort);
  27.             socket.send(reqPacket);
  28.             //3.接收服务器响应的数据
  29.             DatagramPacket resPacket = new DatagramPacket(new byte[4096], 4096);
  30.             socket.receive(resPacket);
  31.             String response = new String(resPacket.getData(),0,resPacket.getLength());
  32.             //4.把响应的数据解析并打印
  33.             System.out.println(response);
  34.         }
  35.     }
  36.     public static void main(String[] args) throws IOException {
  37.         EchoClient echoclient = new EchoClient("127.0.0.1",9090);
  38.         echoclient.start();
  39.     }
  40. }
复制代码
具体代码剖析:
①创建 EchoClient 客户端的类,界说成员变量

  •         socket :客户端UDP套接字
  •         serverIp/serverPort :服务器地点信息

 

②构造方法

  • DatagramSocket ( )  为客户端随机分配一个端标语
  • 保存服务器地点信息


③焦点业务逻辑(start方法)

  • request 用户输入要发送的数据
  • reqPacket 封装要发送的数据

  • request.getBytes() :将用户输入的字符串转换为字节数组
  • request.getBytes().length :获取字节数组的长度,体现要发送的数据巨细
  • InetAddress.getByName(serverIp) :通过服务器的IP地点获取对应的 InetAddress 对象,体现数据要发送到的目的地点
  • serverPort :服务器的端标语,体现数据要发送到的端口


  • socket.send() :调用 send 方法将数据报发送到指定的目的地点和端口
  • resPacket() :吸收服务器发回的相应数据,socket.receive() 是一个壅闭操纵,直到吸收到数据才会继续实行
  • response :提取相应内容,将吸收到的字节数据转换为字符串

④主方法

  • 创建客户端实例,毗连当地服务器的9090端口
  • start 启动客户端

6、UDP编程注意事项

1.数据报巨细限制


  • UDP数据报最大长度理论为65535字节
  • 实际受MTU限制(通常1500字节)
  • 发起保持数据报在1472字节以内(IPv4)
2.数据界限标题


  • 每个 receive() 调用吸收一个完备的数据报
  • 不会出现TCP的“粘包”标题
3.错误处置惩罚


  • 网络不可达
  • 端口未监听
  • 数据包丢失
4.安全性考虑


  • UDP易受DDoS攻击
  • 应考虑实现应用层的验证机制
 

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
继续阅读请点击广告

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
回复

使用道具 举报

×
登录参与点评抽奖,加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表