wjc
2025-04-01 31e89a8697d049410c9d8d5c333cba33223bc9dc
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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
package com.hdl.sdk.link.socket.client;
 
 
import android.net.wifi.WifiManager;
import android.os.SystemClock;
import android.text.TextUtils;
 
import com.hdl.sdk.link.common.config.TopicConstant;
import com.hdl.sdk.link.common.utils.IpUtils;
import com.hdl.sdk.link.common.utils.LogUtils;
import com.hdl.sdk.link.core.bean.LinkPacket;
import com.hdl.sdk.link.core.connect.HDLBusProConnect;
import com.hdl.sdk.link.core.protocol.LinkMessageDecoder;
import com.hdl.sdk.link.core.utils.BusProUtils;
import com.hdl.sdk.link.core.utils.QueueUtils;
import com.hdl.sdk.link.enums.NativeType;
import com.hdl.sdk.link.socket.SocketPool;
import com.hdl.sdk.link.socket.bean.Packet;
import com.hdl.sdk.link.socket.udp.UdpSocketBoot;
import com.hdl.sdk.link.socket.udp.UdpSocketOptions;
import com.hdl.sdk.link.socket.codec.IHandleMessage;
 
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.MulticastSocket;
 
 
/**
 * Created by hxb on 2021/12/12.
 */
public class UdpClient implements IUdpClient {
 
    /**
     * 当前socket
     */
    private MulticastSocket mSocket;
 
    /**
     * 接收数据包
     */
    private DatagramPacket receivePacket;
 
    /**
     * 缓冲区大小
     */
    private final int BUFFER = 2 * 1024;
 
    /**
     * 本地监听IP地址
     */
    private String ipAddress;
    /**
     * 本地监听端口
     */
    private int port;
 
    /**
     * socket配置信息
     */
    private UdpSocketOptions socketOptions;
 
    WifiManager.MulticastLock lock;
 
    /**
     * 初始化参数
     *
     * @param ipAddress     本地监听端口
     * @param port          本地监听端口
     * @param socketOptions
     */
    public UdpClient(String ipAddress, int port, UdpSocketOptions socketOptions) {
        this.ipAddress = ipAddress;
        this.port = port;
        this.socketOptions = socketOptions;
        byte[] receiveByte = new byte[BUFFER];
        receivePacket = new DatagramPacket(receiveByte, receiveByte.length);
        this.lock = socketOptions.getWifiManager().createMulticastLock("UDPwifi");
    }
 
    /**
     * 初始化参数
     *
     * @param ipAddress 本地监听IP地址
     * @param port      本地监听端口
     * @param options
     * @return
     */
    public static UdpSocketBoot init(String ipAddress, int port, UdpSocketOptions options) {
        return new UdpSocketBoot(new UdpClient(ipAddress, port, options));
    }
 
    /**
     * 初始化参数
     *
     * @param port    本地监听端口
     * @param options
     * @return
     */
    public static UdpSocketBoot init(int port, UdpSocketOptions options) {
        return init("0.0.0.0", port, options);
    }
 
    @Override
    public synchronized void bind() throws Exception {
        try {
            //已经绑定过就不用再绑定
            if (null != mSocket) {
                return;
            }
 
            lock.acquire();
            if (TextUtils.isEmpty(ipAddress)) {
                mSocket = SocketPool.getInstance().getUdpSocket(new InetSocketAddress(port));
            } else {
                mSocket = SocketPool.getInstance().getUdpSocket(new InetSocketAddress(Inet4Address.getByName(ipAddress), port));
            }
            //去掉 组地址(光伏app不同网段不允许) 2025年04月01日15:43:58
//            mSocket.joinGroup(InetAddress.getByName(socketOptions.getGroupAddress()));
            mSocket.setSoTimeout(socketOptions.getSoTimeOut());
            mSocket.setBroadcast(true);
//            mSocket.setReuseAddress(true);
 
        } catch (Exception e) {
            throw e;
        }
    }
 
    @Override
    public boolean close() {
        try {
            mSocket.close();
        } catch (Exception e) {
 
        }
        mSocket = null;
        return true;
    }
 
    @Override
    public UdpSocketOptions getOptions() {
        return this.socketOptions;
    }
 
    @Override
    public void onHandleResponse() throws Exception {
        if (mSocket == null) {
            return;
        }
        try {
            mSocket.receive(receivePacket);
        } catch (Exception e) {
//            LogUtils.e("接收到Udp数据包异常,异常信息:" + e.getMessage() + " 线程Id:"+Thread.currentThread().getId());
            SystemClock.sleep(100);//没有数据时,休眠100毫秒,降低cpu
            return;
        }
        if (receivePacket.getLength() == 0) {
            LogUtils.i("接收到Udp数据包,数据包长度为0:" + receivePacket.getAddress().getHostAddress() + ":" + receivePacket.getPort());
            return;
        }
        //排除自己发出去的
        try {
            if (IpUtils.isLocalIpAddress(receivePacket.getAddress().getHostAddress()))
                return;
        } catch (Exception ignored) {
 
        }
 
        try {
            byte[] data = new byte[receivePacket.getLength()];
            System.arraycopy(receivePacket.getData(), 0, data, 0, data.length);
 
            if (mSocket.getLocalPort() == HDLBusProConnect.UDP_PORT) {
                //Bus协议,本身没有主题,默认用上报的主题,方便bus解析器能订阅收到数据
                LinkPacket linkPacket = new LinkPacket(String.format(TopicConstant.NATIVE_BUSPRO_UP, receivePacket.getAddress().getHostAddress()), data);
                linkPacket.setNativeType(NativeType.BusPro);
                QueueUtils.getInstance().add(linkPacket);
            } else {
                //link协议
                socketOptions.getHandleMessage().read(new Packet(data));
            }
 
        } catch (Exception e) {
            LogUtils.i("接收到Udp数据包,处理异常:" + e.getMessage());
        }
    }
 
 
    @Override
    public void sendMsg(String ipAddress, int port, byte[] msg) throws Exception {
        if (msg == null) {
            return;
        }
        DatagramPacket sendPacket = new DatagramPacket(msg, msg.length, InetAddress.getByName(ipAddress), port);
//        if (mSocket != null) {
//            mSocket.send(sendPacket);
//        } else {
        DatagramSocket datagramSocket = new DatagramSocket();
        datagramSocket.setBroadcast(true);
        datagramSocket.send(sendPacket);
        datagramSocket.close();
//        sendPacket = new DatagramPacket(msg, msg.length, InetAddress.getByName(socketOptions.getGroupAddress()), port);
//        MulticastSocket multicastSocket = new MulticastSocket();
//        multicastSocket.setReuseAddress(true);
//        multicastSocket.setBroadcast(true);
//        multicastSocket.setTimeToLive(255);
//        multicastSocket.send(sendPacket);
//        multicastSocket.close();
//        }
    }
}