程序员scholar 程序员scholar
首页
  • Java 基础

    • JavaSE
    • JavaIO
    • JavaAPI速查
  • Java 高级

    • JUC
    • JVM
    • Java新特性
    • 设计模式
  • Web 开发

    • Servlet
    • Java网络编程
  • Web 标准

    • HTML
    • CSS
    • JavaScript
  • 前端框架

    • Vue2
    • Vue3
    • Vue3 + TS
    • 微信小程序
    • uni-app
  • 工具与库

    • jQuery
    • Ajax
    • Axios
    • Webpack
    • Vuex
    • WebSocket
    • 第三方登录
  • 后端与语言扩展

    • ES6
    • Typescript
    • node.js
  • Element-UI
  • Apache ECharts
  • 数据结构
  • HTTP协议
  • HTTPS协议
  • 计算机网络
  • Linux常用命令
  • Windows常用命令
  • SQL数据库

    • MySQL
    • MySQL速查
  • NoSQL数据库

    • Redis
    • ElasticSearch
  • 数据库

    • MyBatis
    • MyBatis-Plus
  • 消息中间件

    • RabbitMQ
  • 服务器

    • Nginx
  • Spring框架

    • Spring6
    • SpringMVC
    • SpringBoot
    • SpringSecurity
  • SpringCould微服务

    • SpringCloud基础
    • 微服务之DDD架构思想
  • 日常必备

    • 开发常用工具包
    • Hutoll工具包
    • IDEA常用配置
    • 开发笔记
    • 日常记录
    • 项目部署
    • 网站导航
    • 产品学习
    • 英语学习
  • 代码管理

    • Maven
    • Git教程
    • Git小乌龟教程
  • 运维工具

    • Docker
    • Jenkins
    • Kubernetes
  • 算法笔记

    • 算法思想
    • 刷题笔记
  • 面试问题常见

    • 十大经典排序算法
    • 面试常见问题集锦
关于
GitHub (opens new window)
首页
  • Java 基础

    • JavaSE
    • JavaIO
    • JavaAPI速查
  • Java 高级

    • JUC
    • JVM
    • Java新特性
    • 设计模式
  • Web 开发

    • Servlet
    • Java网络编程
  • Web 标准

    • HTML
    • CSS
    • JavaScript
  • 前端框架

    • Vue2
    • Vue3
    • Vue3 + TS
    • 微信小程序
    • uni-app
  • 工具与库

    • jQuery
    • Ajax
    • Axios
    • Webpack
    • Vuex
    • WebSocket
    • 第三方登录
  • 后端与语言扩展

    • ES6
    • Typescript
    • node.js
  • Element-UI
  • Apache ECharts
  • 数据结构
  • HTTP协议
  • HTTPS协议
  • 计算机网络
  • Linux常用命令
  • Windows常用命令
  • SQL数据库

    • MySQL
    • MySQL速查
  • NoSQL数据库

    • Redis
    • ElasticSearch
  • 数据库

    • MyBatis
    • MyBatis-Plus
  • 消息中间件

    • RabbitMQ
  • 服务器

    • Nginx
  • Spring框架

    • Spring6
    • SpringMVC
    • SpringBoot
    • SpringSecurity
  • SpringCould微服务

    • SpringCloud基础
    • 微服务之DDD架构思想
  • 日常必备

    • 开发常用工具包
    • Hutoll工具包
    • IDEA常用配置
    • 开发笔记
    • 日常记录
    • 项目部署
    • 网站导航
    • 产品学习
    • 英语学习
  • 代码管理

    • Maven
    • Git教程
    • Git小乌龟教程
  • 运维工具

    • Docker
    • Jenkins
    • Kubernetes
  • 算法笔记

    • 算法思想
    • 刷题笔记
  • 面试问题常见

    • 十大经典排序算法
    • 面试常见问题集锦
关于
GitHub (opens new window)
npm

(进入注册为作者充电)

  • Java网络编程

    • 网络基础知识
    • Java中的网络编程
    • TCP通信编程
    • UDP通信编程
      • 1. 使用 UDP 发送数据
        • 1.1 UDP 通信简介
        • 1.2 构造方法与相关方法
        • 1.3 发送数据的步骤详解
        • 1.4 代码示例:发送数据
      • 2. 使用 UDP 接收数据
        • 2.1 接收数据的步骤详解
        • 2.2 构造方法与相关方法
        • 2.3 代码示例:接收数据
      • 3. UDP 发送数据程序(键盘输入,输入 "886" 结束)
      • 4. UDP 三种通信方式
      • 5. UDP 组播实现详解
    • 网络编程综合案例
  • Java网络编程
  • Java网络编程
scholar
2024-08-24
目录

UDP通信编程

# UDP 通信编程

# 1. 使用 UDP 发送数据

# 1.1 UDP 通信简介

  • UDP(User Datagram Protocol)协议 是一种不可靠的网络协议,它在通信的两端各建立一个 DatagramSocket 对象。由于 UDP 没有连接的概念,因此没有明确的客户端和服务器之分,通信双方只需各自发送和接收数据即可。
  • Java 提供了 DatagramSocket 类用于基于 UDP 协议的网络通信,数据通过 DatagramPacket 进行封装和传输。

# 1.2 构造方法与相关方法

  • 构造方法:

    方法名 说明
    DatagramSocket() 创建数据报套接字并将其绑定到本机地址上的任何可用端口
    DatagramPacket(byte[] buf, int len, InetAddress add, int port) 创建数据包,发送长度为 len 的数据到指定主机的指定端口
  • 相关方法:

    方法名 说明
    void send(DatagramPacket p) 发送数据报包
    void close() 关闭数据报套接字
    void receive(DatagramPacket p) 从此套接字接收数据报包

# 1.3 发送数据的步骤详解

  1. 创建发送端的 DatagramSocket 对象。
  2. 创建要发送的数据,并将其封装到 DatagramPacket 中。
  3. 调用 DatagramSocket 对象的 send 方法发送数据。
  4. 关闭发送端的套接字。

# 1.4 代码示例:发送数据

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

/**
 * @description: UDP 数据发送示例
 * @version: 1.0
 * @author: scholar
 */
public class SendDemo {
    public static void main(String[] args) throws IOException {
        // 1. 创建发送端的 DatagramSocket 对象,用于发送数据。
        // DatagramSocket() 构造数据报套接字并将其绑定到本地主机上的任何可用端口
        DatagramSocket ds = new DatagramSocket();

        // 2. 创建数据并将其打包到 DatagramPacket 中。
        // DatagramPacket(byte[] buf, int length, InetAddress address, int port)
        // 构造一个数据包,将长度为 length 的数据发送到指定主机的指定端口号
        byte[] data = "hello, UDP,我来了".getBytes();
        DatagramPacket dp = new DatagramPacket(data, data.length, InetAddress.getByName("127.0.0.1"), 10086);

        // 3. 调用 DatagramSocket 对象的 send 方法发送数据。
        // void send(DatagramPacket p) 从此套接字发送数据报包
        ds.send(dp);

        // 4. 关闭发送端的 DatagramSocket,释放资源。
        // void close() 关闭此数据报套接字
        ds.close();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

代码解读:

  • DatagramSocket():创建一个数据报套接字,用于发送或接收数据。它绑定到本地主机的任意可用端口。
  • DatagramPacket(byte[] buf, int length, InetAddress address, int port):构造一个数据包,用于发送指定的数据到目标主机和端口。
  • ds.send(dp):发送数据报包到指定的地址和端口。
  • ds.close():关闭套接字,释放系统资源。

# 2. 使用 UDP 接收数据

# 2.1 接收数据的步骤详解

  1. 创建接收端的 DatagramSocket 对象,并指定接收数据的端口号。
  2. 创建一个 DatagramPacket 对象,用于接收数据。
  3. 调用 DatagramSocket 对象的 receive 方法接收数据。
  4. 解析数据包,并将数据输出到控制台。
  5. 关闭接收端的套接字。

# 2.2 构造方法与相关方法

  • 构造方法:

    方法名 说明
    DatagramPacket(byte[] buf, int len) 创建一个 DatagramPacket 用于接收长度为 len 的数据包
  • 相关方法:

    方法名 说明
    byte[] getData() 返回数据缓冲区
    int getLength() 返回要发送的数据的长度或接收的数据的长度

# 2.3 代码示例:接收数据

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

/**
 * @description: UDP 数据接收示例
 * @version: 1.0
 * @author: scholar
 */
public class ReceiveDemo {
    public static void main(String[] args) throws IOException {
        // 1. 创建接收端的 DatagramSocket 对象,指定接收数据的端口号。
        DatagramSocket ds = new DatagramSocket(12345);

        // 2. 创建一个数据包,用于接收数据。
        byte[] buf = new byte[1024];
        DatagramPacket dp = new DatagramPacket(buf, buf.length);

        // 3. 调用 DatagramSocket 对象的 receive 方法接收数据。
        // receive() 方法是阻塞的,直到接收到数据才继续执行。
        ds.receive(dp);

        // 4. 解析数据包,并将数据输出到控制台。
        System.out.println("接收到的数据是:" + new String(dp.getData(), 0, dp.getLength()));

        // 5. 关闭接收端的 DatagramSocket,释放资源。
        ds.close();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

代码解读:

  • DatagramSocket(int port):创建一个绑定到指定端口的套接字,用于接收数据。
  • DatagramPacket(byte[] buf, int len):创建一个用于接收数据的包,指定数据缓冲区和接收数据的最大长度。
  • ds.receive(dp):从套接字接收数据,并将数据存储在数据包中。该方法是阻塞的,直到接收到数据。
  • new String(dp.getData(), 0, dp.getLength()):将接收到的字节数据转换为字符串,并输出到控制台。

总结

  • UDP 是一种无连接的、不可靠的数据传输协议,但其传输效率高,适用于对实时性要求高的应用场景。
  • 通过 DatagramSocket 和 DatagramPacket 类,Java 提供了灵活的 UDP 通信支持,适用于实现简单的消息传输、广播和多播等应用。
  • 发送端和接收端的实现相对独立,没有复杂的连接和握手过程,这使得 UDP 通信更加轻量。

# 3. UDP 发送数据程序(键盘输入,输入 "886" 结束)

案例需求

  • 通过 UDP 发送数据,数据来源于键盘输入,当输入的数据为 "886" 时,发送操作结束。
  • 接收端采用死循环持续接收数据,直到手动结束程序。

代码实现

发送端:

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Scanner;

/**
 * @description: UDP 数据发送 - 键盘输入
 * @version: 1.0
 * @author: scholar
 */
public class SendDemo {
    public static void main(String[] args) throws IOException {
        // 1. 创建发送端的 DatagramSocket 对象,用于发送数据
        DatagramSocket ds = new DatagramSocket();

        // 2. 通过键盘录入获取数据
        Scanner sc = new Scanner(System.in);
        while (true) {
            String input = sc.nextLine();
            // 输入 "886" 时,停止发送数据
            if ("886".equals(input)) {
                break;
            }

            // 3. 将输入的数据转换为字节数组并打包到 DatagramPacket 中
            byte[] data = input.getBytes();
            DatagramPacket dp = new DatagramPacket(data, data.length, InetAddress.getByName("192.168.1.66"), 12345);

            // 4. 发送数据包
            ds.send(dp);
        }

        // 5. 关闭发送端的 DatagramSocket,释放资源
        ds.close();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

代码解读:

  • DatagramSocket(): 创建一个用于发送数据的套接字。
  • Scanner sc = new Scanner(System.in): 通过控制台获取用户输入。
  • DatagramPacket(byte[] buf, int len, InetAddress address, int port): 将用户输入的数据打包,指定接收端的 IP 地址和端口。
  • ds.send(dp): 发送数据包到接收端。
  • ds.close(): 关闭套接字,释放系统资源。

接收端:

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

/**
 * @description: UDP 数据接收 - 死循环接收
 * @version: 1.0
 */
public class ReceiveDemo {
    public static void main(String[] args) throws IOException {
        // 1. 创建接收端的 DatagramSocket 对象,指定接收数据的端口号
        DatagramSocket ds = new DatagramSocket(12345);

        // 2. 死循环,持续接收数据
        while (true) {
            // 3. 创建一个用于接收数据的包
            byte[] buf = new byte[1024];
            DatagramPacket dp = new DatagramPacket(buf, buf.length);

            // 4. 接收数据包(阻塞方法,直到接收到数据)
            ds.receive(dp);

            // 5. 解析数据并输出到控制台
            System.out.println("接收到的数据是:" + new String(dp.getData(), 0, dp.getLength()));
        }

        // 6. 关闭接收端(此处不关闭,因为程序是死循环)
        // ds.close();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

代码解读:

  • DatagramSocket(int port): 创建一个绑定到指定端口的套接字,用于接收数据。
  • DatagramPacket(byte[] buf, int len): 创建一个用于接收数据的包,指定数据缓冲区和接收数据的最大长度。
  • ds.receive(dp): 从套接字接收数据包,阻塞直到接收到数据。
  • new String(dp.getData(), 0, dp.getLength()): 将接收到的数据转换为字符串并输出到控制台。

# 4. UDP 三种通信方式

  • 单播(Unicast): 点对点通信,用于两个主机之间的通信。
  • 组播(Multicast): 将数据发送给特定的一组主机,适用于多点通信。
  • 广播(Broadcast): 将数据发送给局域网上所有的主机,用于网络广播。

# 5. UDP 组播实现详解

实现步骤

发送端:

  1. 创建发送端的 DatagramSocket 对象。
  2. 创建数据并将其打包到 DatagramPacket 中,目标地址为组播地址。
  3. 调用 send 方法发送数据。
  4. 释放资源。

接收端:

  1. 创建接收端的 MulticastSocket 对象,绑定指定端口。
  2. 创建一个数据包用于接收数据。
  3. 将当前计算机加入指定的组播地址。
  4. 接收数据并输出。
  5. 释放资源。

代码实现

组播发送端:

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

/**
 * @description: UDP 组播发送端
 * @version: 1.0
 */
public class ClientDemo {
    public static void main(String[] args) throws IOException {
        // 1. 创建发送端的 DatagramSocket 对象
        DatagramSocket ds = new DatagramSocket();

        // 2. 创建数据并将其打包到 DatagramPacket 中,目标地址为组播地址
        String message = "Hello, 组播!";
        byte[] data = message.getBytes();
        InetAddress groupAddress = InetAddress.getByName("224.0.1.0"); // 组播地址
        int port = 10000; // 组播端口
        DatagramPacket dp = new DatagramPacket(data, data.length, groupAddress, port);

        // 3. 发送数据包
        ds.send(dp);

        // 4. 关闭 DatagramSocket,释放资源
        ds.close();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

组播接收端:

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;

/**
 * @description: UDP 组播接收端
 * @version: 1.0
 */
public class ServerDemo {
    public static void main(String[] args) throws IOException {
        // 1. 创建接收端的 MulticastSocket 对象,绑定指定端口
        MulticastSocket ms = new MulticastSocket(10000);

        // 2. 将当前计算机加入组播地址
        ms.joinGroup(InetAddress.getByName("224.0.1.0"));

        // 3. 创建一个数据包用于接收数据
        DatagramPacket dp = new DatagramPacket(new byte[1024], 1024);

        // 4. 接收数据包
        ms.receive(dp);

        // 5. 解析数据并输出
        byte[] data = dp.getData();
        int length = dp.getLength();
        System.out.println("接收到的组播信息:" + new String(data, 0, length));

        // 6. 关闭 MulticastSocket,释放资源
        ms.close();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

代码解读:

  • 发送端:

    • InetAddress.getByName("224.0.1.0"): 组播地址,范围通常在 224.0.0.0 到 239.255.255.255 之间。
    • DatagramSocket.send(DatagramPacket p): 将数据包发送到指定的组播地址。
  • 接收端:

    • MulticastSocket(int port): 创建一个用于接收组播数据的套接字,绑定到指定端口。
    • joinGroup(InetAddress group): 将当前计算机加入指定的组播组,以便接收组播消息。
    • ms.receive(DatagramPacket dp): 接收数据包并存储在指定的缓冲区中。
    • ms.close(): 关闭套接字并释放资源。

总结

  • 组播是一种高效的多点通信方式,适用于同一网络中的多个主机。
  • 使用组播时,需要特别注意组播地址和端口的选择,以避免与其他服务冲突。
编辑此页 (opens new window)
上次更新: 2024/12/28, 18:32:08
TCP通信编程
网络编程综合案例

← TCP通信编程 网络编程综合案例→

Theme by Vdoing | Copyright © 2019-2025 程序员scholar
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式