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