Java基础网络通信-UDP-一发一收-多发一收
·
UDP(User Datagram Protocol,用户数据报协议)是一种无连接的传输层协议,位于IP协议之上。与TCP不同,UDP不提供可靠性保证、流量控制或拥塞控制机制,仅提供最基本的数据传输功能。
主要应用于语音通话,网络直播等
使用Java中的java.net.DatagramSocket类
一、DatagramSocket:通信端点
DatagramSocket用于创建 UDP 通信的客户端或服务端套接字,负责数据的发送和接收。
构造器
| 构造器 | 说明 |
|---|---|
public DatagramSocket() |
创建客户端的 Socket 对象,系统会随机分配一个端口号。 |
public DatagramSocket(int port) |
创建服务端的 Socket 对象,并指定端口号。 |
常用方法
| 方法 | 说明 |
|---|---|
public void send(DatagramPacket dp) |
发送数据包。 |
public void receive(DatagramPacket p) |
接收数据包,该方法会阻塞直到有数据到达。 |
二、DatagramPacket:数据载体
DatagramPacket用于封装 UDP 通信中的数据,包括要发送或接收的字节数组、目标地址和端口等信息。
构造器
表格
| 构造器 | 说明 |
|---|---|
public DatagramPacket(byte[] buf, int length, InetAddress address, int port) |
创建发送用的数据包对象,包含数据、目标 IP 和端口。 |
public DatagramPacket(byte[] buf, int length) |
创建接收用的数据包对象,指定接收数据的缓冲区和长度。 |
常用方法
表格
| 方法 | 说明 |
|---|---|
public int getLength() |
获取实际接收到的字节个数。 |
三、核心使用逻辑
- 服务端:使用带端口的
DatagramSocket构造器创建套接字,然后调用receive()方法等待客户端数据。 - 客户端:使用无参
DatagramSocket构造器创建套接字,构造包含目标信息的DatagramPacket,再调用send()方法发送。 - 数据交互:所有通信都基于数据包(
DatagramPacket)进行,不建立持久连接。
案例:
多发一收
多发一收即多个客户端发送数据,一个服务端接受数据
客户端代码
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Scanner;
public class UdpClient {
// 定义服务端的端口(建议和客户端端口区分开,避免冲突)
private static final int SERVER_PORT = 10000;
// 定义服务端的IP地址(本地测试用回环地址)
private static final String SERVER_IP = "127.0.0.1";
public static void main(String[] args) {
// 1. 声明核心对象(Socket是UDP通信的端点,try-with-resources自动关闭Scanner)
DatagramSocket clientSocket = null;
try (Scanner scanner = new Scanner(System.in)) {
// 2. 创建UDP客户端Socket(无参构造:系统自动分配随机端口)
clientSocket = new DatagramSocket();
System.out.println("UDP客户端已启动,可输入消息发送(输入exit退出)...");
// 3. 循环接收用户输入并发送
while (true) {
// 提示用户输入
System.out.print("请输入要发送的内容:");
String inputData = scanner.nextLine().trim();
// 4. 退出逻辑(关闭资源+终止循环,避免异常)
if ("exit".equals(inputData)) {
System.out.println("用户主动退出,客户端正在关闭...");
break;
}
// 5. 空输入校验(提升用户体验)
if (inputData.isEmpty()) {
System.out.println("输入内容不能为空,请重新输入!");
continue;
}
// 6. 封装UDP数据包(核心步骤:数据+目标地址+目标端口)
// 6.1 把字符串转字节数组(UDP传输的是字节数据)
byte[] dataBytes = inputData.getBytes();
// 6.2 获取服务端的IP地址对象(127.0.0.1=本地回环地址)
InetAddress serverAddress = InetAddress.getByName(SERVER_IP);
// 6.3 创建数据包:包含要发送的数据、数据长度、服务端IP、服务端端口
DatagramPacket sendPacket = new DatagramPacket(
dataBytes, // 要发送的字节数据
dataBytes.length,// 数据长度
serverAddress, // 目标IP地址
SERVER_PORT // 目标端口
);
// 7. 发送数据包
clientSocket.send(sendPacket);
System.out.println("消息发送成功:" + inputData);
}
} catch (Exception e) {
System.err.println("客户端发送消息出错:" + e.getMessage());
e.printStackTrace();
} finally {
// 8. 最终关闭Socket(释放端口资源)
if (clientSocket != null && !clientSocket.isClosed()) {
clientSocket.close();
System.out.println("客户端Socket已关闭,资源释放完成");
}
}
}
}
服务端代码
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class UdpServer {
// 服务端监听端口(与客户端指定的服务端端口一致)
private static final int SERVER_PORT = 10000;
public static void main(String[] args) {
DatagramSocket serverSocket = null;
try {
// 1. 创建服务端Socket并绑定端口
serverSocket = new DatagramSocket(SERVER_PORT);
System.out.println("UDP服务端启动,监听端口:" + SERVER_PORT);
byte[] buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
// 2. 持续接收客户端消息
while (true) {
serverSocket.receive(packet); // 阻塞接收数据
// 3. 解析客户端信息和消息
InetAddress clientIp = packet.getAddress();
int clientPort = packet.getPort();
String msg = new String(packet.getData(), 0, packet.getLength());
// 4. 输出核心信息
System.out.println("客户端[" + clientIp + ":" + clientPort + "]:" + msg);
// 重置数据包长度,避免残留数据
packet.setLength(buffer.length);
}
} catch (IOException e) {
System.err.println("服务端异常:" + e.getMessage());
} finally {
// 释放资源
if (serverSocket != null && !serverSocket.isClosed()) {
serverSocket.close();
}
}
}
}
一发多收
代码同上,将客户端的while循环部分去除即可
使用IDEA多开测试即可本地测试
更多推荐




所有评论(0)