// 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());
|
}
|
}
|
}
|
});
|
}
|
}
|