UDP通信编程方法详解
发送端
发送端需要做到以下几件事:
1、使用DatagramSocket
指定端口,创建发送端
2、准备数据,转成字节数组
3、封装成DatagramPacket
包裹,需要指定目的地
4、发送包裹
5、释放资源
简要的示例如下:
public class UdpClient {
public static void main(String[] args) throws IOException {
System.out.println("发送方启动中.......");
// 1、使用DatagramSocket指定端口,创建发送端
DatagramSocket client = new DatagramSocket(8888);
// 2、准备数据 一定转成字节数组
String data = "JOJO is YaoMing";
byte[] datas = data.getBytes();
//3、封装成DatagramPacket包裹,需要指定目的地
DatagramPacket packet = new DatagramPacket(datas, 0, datas.length,
new InetSocketAddress("localhost", 9999));
// 4、发送包裹 send(DatagramPacket p)
client.send(packet);
// 5、释放资源
client.close();
}
}
接收端
接收端需要做到以下几件事:
1、使用DatagramSocket
指定端口,创建接收端
2、准备容器,封装成DatagramPacket
包裹
3、阻塞式接收包裹
4、分析数据
5、释放资源
示例如下:
public class UdpServer {
public static void main(String[] args) throws Exception {
System.out.println("接收方启动中");
// 1、使用DatagramSocket指定端口,创建接收端
DatagramSocket server = new DatagramSocket(9999);
// 2、准备容器 封装成DatagramPacket包裹
byte[] container = new byte[1024 * 60];
DatagramPacket packet = new DatagramPacket(container, 0, container.length);
// 3、阻塞式接收包裹 receive(DatagramPacket p)
server.receive(packet);
// 4、分析数据
byte[] datas = packet.getData();
int len = packet.getLength();
System.out.println(new String(datas, 0, len));
// 5、释放资源
server.close();
}
}
实现教师和学生一对一网络聊天
这里我们要基于控制台实现一个网络通讯,具体用到的知识包括上面讲的UDP通信,还包含了多线程的基础知识。
我们首先封装了发送信息的代码,和接收信息的代码。
TalkSend.java
/**
* 发送端:使用面向对象封装
* 多线程 发送消息
*
* @Author Nino 2019/10/22
*/
public class TalkSend implements Runnable {
/**
* 指定端口 创建发送端
*/
private DatagramSocket client;
/**
* 准备发送的数据
*/
private BufferedReader br;
/**
* 对方的IP地址
*/
private String toIP;
/**
* 对方的端口
*/
private int toPort;
public TalkSend(int port, String toIP, int toPort) {
this.toIP = toIP;
this.toPort = toPort;
try {
client = new DatagramSocket(port);
br = new BufferedReader(new InputStreamReader(System.in));
} catch (SocketException e) {
e.printStackTrace();
}
}
@Override
public void run() {
while (true) {
String data;
try {
data = br.readLine();
byte[] datas = data.getBytes();
// 封装成包
DatagramPacket packet = new DatagramPacket(datas, 0, datas.length,
new InetSocketAddress(toIP, toPort));
client.send(packet);
// 中断循环条件
if (data.equals("bye")) {
break;
}
} catch (IOException e) {
e.printStackTrace();
}
}
// 释放资源
client.close();
}
}
TalkReceive.java
/**
* 接收端:使用面向对象封装
* 多线程 接收消息
*
* @Author Nino 2019/10/22
*/
public class TalkReceive implements Runnable {
/**
* 接收端
*/
private DatagramSocket server;
/**
* 从哪来
*/
private String from;
public TalkReceive(int port, String from) {
this.from = from;
try {
server = new DatagramSocket(port);
} catch (SocketException e) {
e.printStackTrace();
}
}
@Override
public void run() {
while (true) {
// 创建容器 并打包
byte[] container = new byte[1024 * 64];
DatagramPacket packet = new DatagramPacket(container, 0, container.length);
try {
// 阻塞式接收
server.receive(packet);
//分析数据
byte[] datas = packet.getData();
String data = new String(datas, 0, datas.length);
System.out.println(from + ":" + data);
if (data.equals("bye")) {
break;
}
} catch (IOException e) {
e.printStackTrace();
}
}
server.close();
}
}
封装完毕后,只需要建学生和老师,然后分别创建发送和接收两个线程,即可实现通信。
注意端口不能被重复占用,同时校对好对方的IP地址,本机只需要输入localhost
TalkStudent.java
public class TalkStudent {
public static void main(String[] args) {
// 接收
new Thread(new TalkReceive(9999, "teacher")).start();
// 发送
new Thread(new TalkSend(6666, "localhost", 7777)).start();
}
}
TalkTeacher.java
public class TalkTeacher {
public static void main(String[] args) {
// 发送
new Thread(new TalkSend(8888, "localhost", 9999)).start();
// 接收
new Thread(new TalkReceive(7777, "student")).start();
}
}