UDP 发送端与接收端

一、核心概念:端口分工与通信流程

UDP 通信中,发送端和接收端通过约定的端口完成数据对接,两者角色不同,端口作用也不同:

  1. 接收端:需绑定固定端口(如 9000),作为 “监听端口”,专门等待接收数据(类似 “固定门牌号”)。
  2. 发送端:需指定目标端口(必须与接收端的固定端口一致,如 9000),作为 “发送目标”(类似 “收件人门牌号”);发送端自身端口可随机分配(临时端口)或固定。
  3. 通信流程:接收端先启动并监听端口 → 发送端向目标端口发送数据 → 接收端从监听端口接收数据。

二、完整代码示例

1. 接收端(Receiver)

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
package test1029;

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

public class Receiver {
public static void main(String[] args) throws IOException {
// 1. 创建DatagramSocket,绑定固定端口9000(监听此端口的数据)
DatagramSocket socket = new DatagramSocket(9000);
System.out.println("接收端已启动,监听9000端口...");

// 2. 创建字节数组和数据报,用于接收数据(缓冲区)
byte[] buff = new byte[1024]; // 缓冲区大小(可调整)
DatagramPacket packet = new DatagramPacket(buff, buff.length);

// 3. 阻塞等待接收数据(直到收到数据才继续执行)
socket.receive(packet);

// 4. 解析接收的数据:获取发送端IP、端口和数据内容
String senderIp = packet.getAddress().getHostAddress(); // 发送端IP
int senderPort = packet.getPort(); // 发送端端口(可能是临时端口)
String data = new String(packet.getData(), 0, packet.getLength()); // 数据内容(0到有效长度,避免空字符)

// 5. 打印接收结果
System.out.println("收到来自 " + senderIp + "(端口:" + senderPort + ")的消息:" + data);

// 6. 关闭套接字,释放资源
socket.close();
}
}

2. 发送端(Sender)

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
package test1029;

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

public class Sender {
public static void main(String[] args) throws IOException {
// 1. 创建DatagramSocket(不指定端口,系统自动分配临时端口)
DatagramSocket socket = new DatagramSocket();

// 2. 准备要发送的数据(字符串转字节数组,网络传输需用字节)
String str = "解放日本";
byte[] buff = str.getBytes();

// 3. 创建数据报,封装数据、目标IP和目标端口(9000,与接收端一致)
// 目标IP:127.0.0.1(本机);若发给其他设备,替换为对方的IP(如192.168.1.105)
DatagramPacket packet = new DatagramPacket(
buff,
buff.length,
InetAddress.getByName("127.0.0.1"), // 目标IP地址
9000 // 目标端口(必须与接收端监听的端口一致)
);

// 4. 发送数据
socket.send(packet);
System.out.println("数据发送成功!");

// 5. 关闭套接字
socket.close();
}
}

三、关键说明

  1. 运行顺序:必须先启动接收端(确保 9000 端口被监听),再启动发送端,否则发送的数据会因 “无人接收” 而丢失。
  2. 端口含义
    • 接收端的9000:固定监听端口,是通信的 “约定端口”,发送端必须匹配。
    • 发送端的端口(如 57007):系统随机分配的临时端口(若代码中new DatagramSocket()未指定端口),接收端可通过packet.getPort()获取,用于回复消息。
  3. 跨设备通信:若发送给其他设备,只需将发送端的InetAddress.getByName("127.0.0.1")改为对方的 IP(如局域网 IP192.168.1.105或公网 IP),确保双方网络互通且端口未被防火墙拦截。

四、常见问题

  • 接收端收不到数据?→ 检查是否先启动接收端、目标端口是否为 9000、IP 是否正确、防火墙是否拦截。
  • 发送端端口不固定?→ 若需固定发送端端口,可在创建DatagramSocket时指定(如new DatagramSocket(8000)),此时接收端会打印 8000。