// UdpListener.java package home; import java.io.IOException; import java.net.*; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class UdpListener extends NetworkBase { private DatagramSocket socket; private ExecutorService receiverThread; private byte[] buffer = new byte[1024]; public UdpListener(String host, int port) { this.host = host; this.port = port; } @Override public boolean start() throws Exception { try { InetAddress localAddress = InetAddress.getByName(host); socket = new DatagramSocket(port, localAddress); socket.setSoTimeout(1000); // 设置超时以便可以检查停止状态 isRunning.set(true); startReceiver(); notifyStatus("UDP监听已启动 - " + host + ":" + port, true); return true; } catch (BindException e) { notifyError("端口 " + port + " 被占用,请选择其他端口"); return false; } catch (Exception e) { notifyError("启动UDP监听失败: " + e.getMessage()); return false; } } @Override public void stop() { isRunning.set(false); if (socket != null && !socket.isClosed()) { socket.close(); } if (receiverThread != null) { receiverThread.shutdownNow(); } notifyStatus("UDP监听已停止", false); } @Override public boolean sendData(String data) throws Exception { // UDP发送数据需要目标地址,这里不实现发送功能 return false; } /** * 向指定IP和端口发送数据 - 新增方法 * @param data 要发送的数据字节数组 * @param ip 目标IP地址 * @param port 目标端口 * @return 是否发送成功 */ public boolean sendDataTo(byte[] data, String ip, int port) { if (socket == null || socket.isClosed() || !isRunning.get()) { notifyError("UDP Socket未就绪,无法发送数据"); return false; } try { InetAddress targetAddress = InetAddress.getByName(ip); DatagramPacket packet = new DatagramPacket(data, data.length, targetAddress, port); socket.send(packet); // 记录发送成功 System.out.println("UDP数据已发送至 " + ip + ":" + port + ",数据长度: " + data.length); return true; } catch (UnknownHostException e) { notifyError("未知的主机地址: " + ip); return false; } catch (IOException e) { notifyError("发送UDP数据失败: " + e.getMessage()); return false; } catch (Exception e) { notifyError("发送数据时发生错误: " + e.getMessage()); return false; } } /** * 向指定IP和端口发送字符串数据 - 新增方法 * @param data 要发送的字符串数据 * @param ip 目标IP地址 * @param port 目标端口 * @return 是否发送成功 */ public boolean sendDataTo(String data, String ip, int port) { if (data == null) { return false; } return sendDataTo(data.getBytes(), ip, port); } @Override public boolean isConnected() { return isRunning.get() && socket != null && !socket.isClosed(); } private void startReceiver() { receiverThread = Executors.newSingleThreadExecutor(); receiverThread.execute(() -> { while (isRunning.get() && socket != null && !socket.isClosed()) { try { DatagramPacket packet = new DatagramPacket(buffer, buffer.length); socket.receive(packet); // 提取接收到的数据 byte[] receivedData = new byte[packet.getLength()]; System.arraycopy(packet.getData(), packet.getOffset(), receivedData, 0, packet.getLength()); String fromAddress = packet.getAddress().getHostAddress() + ":" + packet.getPort(); // 使用统一的数据处理方法 - 修改这里 handleReceivedData(receivedData, fromAddress); } catch (SocketTimeoutException e) { // 超时正常,继续循环检查停止状态 } catch (Exception e) { if (isRunning.get()) { notifyError("接收数据错误: " + e.getMessage()); } } } }); } }