zsh_root
2025-12-10 8d662de2fd262b3a485f16e197cb4d0ca2a61cdf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
// 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());
                    }
                }
            }
        });
    }
}