1 介绍
2 Java 实现 UDP 消息发送
2.1 客户端
public class UDPClientTest {
public static void main(String[] args) {
DatagramSocket socket = null;
try {
// 建立一个 Socket
socket = new DatagramSocket();
// 明确目标地址
InetAddress address = InetAddress.getByName("127.0.0.1");
int port = 8888;
// 创建包
String msg = "Hello, I'm PkyShare";
DatagramPacket packet = new DatagramPacket(msg.getBytes(), 0, msg.getBytes().length, address, port);
// 发送
socket.send(packet);
}
catch (Exception e) {
e.printStackTrace();
}
finally {
if(socket != null) {
socket.close();
}
}
}
}
2.2 服务端
public class UDPServerTest {
public static void main(String[] args) {
DatagramSocket socket = null;
try {
// 开放端口
socket = new DatagramSocket(8888);
// 读取数据包
byte[] bytes = new byte[1024];
DatagramPacket packet = new DatagramPacket(bytes, 0, bytes.length);
// 接收
socket.receive(packet);
System.out.println(packet.getAddress());
System.out.println((new String(packet.getData(), 0, packet.getLength())));
}
catch (Exception e) {
e.printStackTrace();
}
finally {
if(socket != null) {
socket.close();
}
}
}
}
2.3 启动测试
因为 UDP 并不需要建立连接,只需要知道目标地址即可。因此先启动哪个都不会报错。但是如果先启动客户端,则服务端接收不了。以下是先启动服务端,在启动客户端的结果:
控制台输出:
/127.0.0.1 Hello, I'm PkyShare
3 单一聊天
单方面发送消息
3.1 客户端
public class UDPClientTest {
public static void main(String[] args) {
DatagramSocket socket = null;
String msg = "";
try {
// 建立一个 Socket
socket = new DatagramSocket();
while (!"-1".equals(msg)) {
// 创建包
BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); // 控制台输入
String data = br.readLine();
byte[] bytes = data.getBytes();
msg = new String(bytes, 0, bytes.length);
DatagramPacket packet = new DatagramPacket(bytes, 0, bytes.length, InetAddress.getByName("127.0.0.1"), 8888);
// 发送
socket.send(packet);
}
}
catch (Exception e) {
e.printStackTrace();
}
finally {
if(socket != null) {
socket.close();
}
}
}
}
3.2 服务端
public class UDPServerTest {
public static void main(String[] args) {
DatagramSocket socket = null;
String msg = "";
try {
// 开放端口
socket = new DatagramSocket(8888);
while (!"-1".equals(msg)) {
// 读取数据包
byte[] bytes = new byte[1024];
DatagramPacket packet = new DatagramPacket(bytes, 0, bytes.length);
// 接收
socket.receive(packet);
msg = new String(packet.getData(), 0, packet.getLength());
System.out.println(msg);
}
}
catch (Exception e) {
e.printStackTrace();
}
finally {
if(socket != null) {
socket.close();
}
}
}
}
3.3 测试结果
客户端依次发送
Hello, I'm PkyShare Bye -1
服务端依次接受到
Hello, I'm PkyShare Bye -1
4 多线程创建简易聊天室
聊天室中,每个人都有【说话】和【接收】两种能力,因此对【说话】和【接收】分别创建线程。
4.1 Talk
package com.cq.auto.parts.commons.service.test;
public class Talk implements Runnable {
DatagramSocket socket;
BufferedReader br;
String fromIp; // 接收方 ip
int fromPort; // 接收方端口
public Talk(String fromIp, int fromPort) {
this.fromIp = fromIp;
this.fromPort = fromPort;
try {
this.socket = new DatagramSocket();
this.br = new BufferedReader(new InputStreamReader(System.in));
} catch (SocketException e) {
e.printStackTrace();
}
}
@Override
public void run() {
String inputMsg; // 控制台输入的消息
try {
do {
// 创建包
inputMsg = br.readLine();
byte[] bytes = inputMsg.getBytes();
DatagramPacket packet = new DatagramPacket(bytes, 0, bytes.length, InetAddress.getByName(fromIp), fromPort);
// 发送
socket.send(packet);
}while (!"bye".equalsIgnoreCase(inputMsg));
}
catch (Exception e) {
e.printStackTrace();
}
finally {
if(socket != null) {
socket.close();
}
}
}
}
3.2 Receive
public class Receive implements Runnable {
DatagramSocket socket;
String senderName; // 发送方名字
int port; // 接收方端口
public Receive(String senderName, int port) {
this.senderName = senderName;
this.port = port;
// 开放端口
try {
socket = new DatagramSocket(port);
} catch (SocketException e) {
e.printStackTrace();
}
}
@Override
public void run() {
String receiveMsg;
try {
do {
// 读取数据包
byte[] bytes = new byte[1024];
DatagramPacket packet = new DatagramPacket(bytes, 0, bytes.length);
// 接收
socket.receive(packet);
receiveMsg = new String(packet.getData(), 0, packet.getLength());
System.out.println(senderName + ":" + receiveMsg);
}while (!"bye".equalsIgnoreCase(receiveMsg));
}
catch (Exception e) {
e.printStackTrace();
}
finally {
if(socket != null) {
socket.close();
}
}
}
}
4.3 创建学生客户端
public class StuMainTest {
public static void main(String[] args) {
new Thread(new Talk("127.0.0.1", 8888)).start(); // 创建并启动说话的线程
new Thread(new Receive("teacher", 9999)).start(); // 创建并启动接收的线程
}
}
4.4 创建老师客户端
public class TeacherMainTest {
public static void main(String[] args) {
new Thread(new Talk("127.0.0.1", 9999)).start(); // 创建说话的线程
new Thread(new Receive("stu", 8888)).start(); // 创建接收的线程
}
}
4.5 测试结果
学生控制台输出:
您好老师 teacher:你好 我想学网络编程 teacher:好的,我之后教你 谢谢老师 teacher:不客气 bye teacher:bye Process finished with exit code 0
老师控制台输出:
stu:您好老师 你好 stu:我想学网络编程 好的,我之后教你 stu:谢谢老师 不客气 stu:bye bye Process finished with exit code 0