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 发送数据的步骤详解
- 创建发送端的
DatagramSocket
对象。 - 创建要发送的数据,并将其封装到
DatagramPacket
中。 - 调用
DatagramSocket
对象的send
方法发送数据。 - 关闭发送端的套接字。
# 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
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 接收数据的步骤详解
- 创建接收端的
DatagramSocket
对象,并指定接收数据的端口号。 - 创建一个
DatagramPacket
对象,用于接收数据。 - 调用
DatagramSocket
对象的receive
方法接收数据。 - 解析数据包,并将数据输出到控制台。
- 关闭接收端的套接字。
# 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
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
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
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 组播实现详解
实现步骤
发送端:
- 创建发送端的
DatagramSocket
对象。 - 创建数据并将其打包到
DatagramPacket
中,目标地址为组播地址。 - 调用
send
方法发送数据。 - 释放资源。
接收端:
- 创建接收端的
MulticastSocket
对象,绑定指定端口。 - 创建一个数据包用于接收数据。
- 将当前计算机加入指定的组播地址。
- 接收数据并输出。
- 释放资源。
代码实现
组播发送端:
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
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
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