在线咨询(本地)
线程一、TalkSend()
package XiaoShuai; // 包名,属于XiaoShuai这个包
import java.io.BufferedReader; // 导入缓冲读取器,用于读取输入
import java.io.IOException; // 导入IO异常处理
import java.io.InputStreamReader; // 导入输入流读取器
import java.net.DatagramPacket; // 导入UDP数据包类
import java.net.DatagramSocket; // 导入UDP套接字类
import java.net.InetSocketAddress; // 导入IP地址和端口类
import java.net.SocketException; // 导入套接字异常类
public class TalkSend implements Runnable { // 定义一个可以被线程运行的发送类
DatagramSocket socket = null; // 声明UDP套接字
BufferedReader reader = null; // 声明输入读取器
private int fromPort; // 发送消息的端口
private String toIP; // 接收方IP
private int toPort; // 接收方端口
public TalkSend(int fromPort, String toIP,int toPort) { // 构造器,初始化端口和IP
this.fromPort = fromPort; // 保存发送端口
this.toPort = toPort; // 保存接收端口
this.toIP = toIP; // 保存接收端IP
try {
socket = new DatagramSocket(fromPort); // 创建UDP套接字并绑定发送端口
reader = new BufferedReader(new InputStreamReader(System.in)); // 初始化键盘输入读取器
} catch (SocketException e) { // 捕获套接字异常
throw new RuntimeException(e); // 抛出运行时异常
}
}
@Override
public void run() { // 实现线程run方法
while (true) { // 无限循环,持续发送消息
try {
String data = reader.readLine(); // 从键盘读取一行输入
byte[] datas = data.getBytes(); // 将字符串信息转为字节数组
DatagramPacket packet = new DatagramPacket(datas, 0, datas.length, new InetSocketAddress(this.toIP, this.toPort)); // 创建UDP数据包,指定目标地址和端口
socket.send(packet); // 发送UDP数据包
if (data.equals("bye")) { // 如果输入为"bye"
break; // 退出循环,结束发送
}
} catch (IOException e) { // 捕获IO异常
throw new RuntimeException(e); // 抛出运行时异常
}
}
socket.close(); // 关闭UDP套接字,释放资源
}
}
线程二、TalkReceive()
package XiaoShuai; // 包名,属于XiaoShuai这个包
import java.io.IOException; // 导入IO异常处理
import java.net.DatagramPacket; // 导入UDP数据包类
import java.net.DatagramSocket; // 导入UDP套接字类
import java.net.SocketException; // 导入套接字异常类
public class TalkReceive implements Runnable{ // 定义一个可以被线程运行的接收类
DatagramSocket socket = null; // 声明UDP套接字
private int port; // 接收消息的端口
private String msgFrom; // 发消息的人名(显示用)
public TalkReceive(int port,String msgFrom) { // 构造器,初始化端口和名称
this.port = port; // 保存端口
this.msgFrom = msgFrom; // 保存发送者名字
try {
socket = new DatagramSocket(port); // 创建UDP套接字并绑定接收端口
} catch (SocketException e) { // 捕获套接字异常
throw new RuntimeException(e); // 抛出运行时异常
}
}
@Override
public void run() { // 实现线程run方法
while(true){ // 无限循环,持续接收消息
//准备接受包裹
try {
byte[] container = new byte[1024]; // 创建字节数组容器,用于存放接收数据
DatagramPacket packet = new DatagramPacket(container,0,container.length); // 创建UDP数据包,指定容器
socket.receive(packet);//阻塞式接收包裹
//断开连接 bye
byte[] data = packet.getData(); // 获取包裹里的数据
String receiveData = new String(data,0,data.length); // 将字节数据转换为字符串
System.out.println(msgFrom +":" + receiveData); // 打印发送者名字和内容
if(receiveData.equals("bye")){ // 如果内容为“bye”
break; // 退出循环,结束接收
}
} catch (IOException e) { // 捕获IO异常
throw new RuntimeException(e); // 抛出运行时异常
}
}
socket.close(); // 关闭UDP套接字,释放资源
}
}
学生聊天主类
package XiaoShuai; // 包名,属于XiaoShuai这个包
public class TalkStudent { // 学生聊天主类
public static void main(String[] args) { // 主方法,程序入口
new Thread(new TalkSend(7777,"localhost",9999)).start(); // 启动发送线程:本地7777端口发消息到9999端口
new Thread(new TalkReceive(8888,"老师")).start(); // 启动接收线程:监听8888端口,显示老师发来的消息
}
}
老师聊天主类
package XiaoShuai; // 包名,属于XiaoShuai这个包
public class TalkTeacher { // 老师聊天主类
public static void main(String[] args) { // 主方法,程序入口
new Thread(new TalkSend(5555,"localhost",8888)).start(); // 启动发送线程:本地5555端口发消息到8888端口
new Thread(new TalkReceive(9999,"学生")).start(); // 启动接收线程:监听9999端口,显示学生发来的消息
}
}