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