hxb
2022-03-21 0188dee359636723190f0f67a6b674b7b08f7bef
HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/client/UdpClient.java
@@ -1,208 +1,174 @@
package com.hdl.sdk.socket.client;
import android.util.Log;
import android.text.TextUtils;
import com.hdl.sdk.common.HDLSdk;
import com.hdl.sdk.common.utils.IpUtils;
import com.hdl.sdk.common.utils.LogUtils;
import com.hdl.sdk.common.utils.ThreadToolUtils;
import com.hdl.sdk.socket.SocketBoot;
import com.hdl.sdk.socket.SocketOptions;
import com.hdl.sdk.socket.SocketPool;
import com.hdl.sdk.socket.annotation.ConnectStatus;
import com.hdl.sdk.socket.udp.UdpSocketBoot;
import com.hdl.sdk.socket.udp.UdpSocketOptions;
import com.hdl.sdk.socket.codec.IHandleMessage;
import com.hdl.sdk.socket.listener.ConnectStatusListener;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.util.List;
import java.net.SocketAddress;
import java.util.concurrent.atomic.AtomicBoolean;
/**
 * Created by Tong on 2021/9/15.
 * 组播需要android.permission.CHANGE_WIFI_MULTICAST_STATE权限
 * MulticastSocket
 * Created by hxb on 2021/12/12.
 */
public class UdpClient implements IClient {
    private static DatagramSocket mSocket;
    private DatagramPacket receivePacket;
    private final int BUFFER = 4 * 1024;
    private final byte[] receiveByte;
    private final String ip;
    private final int port;
    private int monitorPort;
    private int sendPort;
    private SocketOptions socketOptions;
    private final AtomicBoolean isConnect = new AtomicBoolean(false);
public class UdpClient implements IUdpClient {
    /**
     * @param sendPort -1 表示随机端口
     * 当前socket
     */
    private UdpClient(String ip, int port, int monitorPort, int sendPort, SocketOptions socketOptions) {
    private  DatagramSocket mSocket;
    /**
     * 接收数据包
     */
    private DatagramPacket receivePacket;
    /**
     * 缓冲区大小
     */
    private final int BUFFER = 2 * 1024;
    /**
     * 本地监听IP地址
     */
    private String ipAddress;
    /**
     * 本地监听端口
     */
    private int port;
    /**
     * socket配置信息
     */
    private UdpSocketOptions socketOptions;
    /**
     * 初始化参数
     * @param ipAddress 本地监听端口
     * @param port 本地监听端口
     * @param socketOptions
     */
    private UdpClient(String ipAddress,int port, UdpSocketOptions socketOptions) {
        this.ipAddress = ipAddress;
        this.port = port;
        this.socketOptions = socketOptions;
        this.ip = ip;
        this.port = port;
        this.sendPort = sendPort;
        this.monitorPort = monitorPort;
        this.receiveByte = new byte[BUFFER];
        byte[] receiveByte = new byte[BUFFER];
        receivePacket = new DatagramPacket(receiveByte, receiveByte.length);
    }
    public UdpClient(String ip, int port) {
        this.ip = ip;
        this.port = port;
        this.receiveByte = new byte[BUFFER];
    /**
     * 初始化参数
     * @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));
    }
    public static SocketBoot init(String ip, int port, int monitorPort, int sendPort, SocketOptions options) {
        return new SocketBoot(new UdpClient(ip, port, monitorPort, sendPort, options));
    /**
     * 初始化参数
     * @param port 本地监听端口
     * @param options
     * @return
     */
    public static UdpSocketBoot init(int port, UdpSocketOptions options) {
        return init(null, port, options);
    }
    public static SocketBoot init(String ip, int port, int monitorPort, SocketOptions options) {
        return init(ip, port, monitorPort, -1, options);
    }
    public static SocketBoot init(String ip, int port, SocketOptions options) {
        return init(ip, port, port, -1, options);
    }
    @Override
    public void connect() throws Exception {
    public void bind() throws Exception {
        try {
            mSocket = SocketPool.getInstance().getUdpSocket(new InetSocketAddress(monitorPort));
            //已经绑定过就不用再绑定
            if (null != mSocket) {
                return;
            }
            if (TextUtils.isEmpty(ipAddress)) {
                mSocket = SocketPool.getInstance().getUdpSocket(new InetSocketAddress(port));
            }
            mSocket.setBroadcast(true);
            mSocket.setReuseAddress(true);
            isConnect.set(true);
            if (receivePacket == null) {
                receivePacket = new DatagramPacket(receiveByte, BUFFER);
            }
        } catch (Exception e) {
            isConnect.set(false);
            LogUtils.e("初始化Socket 失败:" + e.getMessage());
            throw e;
        }
    }
    @Override
    public void disconnect() {
        if (mSocket != null) {
    public boolean close() {
        try {
            mSocket.close();
        } catch (Exception e) {
        }
        isConnect.set(false);
        mSocket = null;
        return true;
    }
    @Override
    public boolean isConnect() {
        return isConnect.get();
    }
    @Override
    public synchronized SocketOptions getOptions() {
        if (socketOptions == null) {
            socketOptions = new SocketOptions();
        }
        return socketOptions;
    public UdpSocketOptions getOptions() {
        return this.socketOptions;
    }
    @Override
    public void onHandleResponse() throws Exception {
        if (receivePacket == null || mSocket == null) {
        if (mSocket == null) {
            return;
        }
        try {
            mSocket.receive(receivePacket);
        } catch (IOException e) {
            e.printStackTrace();
            isConnect.set(false);
        }
        if (receivePacket.getLength() == 0) {
            return;
        }
        //排除自己发出去的
        try {
            if (receivePacket.getAddress().getHostAddress()
                    .equals(IpUtils.getIP(HDLSdk.getInstance().getContext()))) {
            if (IpUtils.isLocalIpAddress(receivePacket.getAddress().getHostAddress()))
                return;
            }
        } catch (Exception ignored) {
        }
        IHandleMessage handleMessage = getOptions().getHandleMessage();
        if (handleMessage != null) {
            handleMessage.read(receivePacket.getData());
        }
        final String receive = new String(receivePacket.getData(), 0, receivePacket.getLength());
        try {
            LogUtils.i("接收到Udp数据包,网络地址:" + receivePacket.getAddress().getHostAddress() + ":" + receivePacket.getPort());
        LogUtils.d("---->", receive + " from " + receivePacket.getAddress().getHostAddress() + ":" + receivePacket.getPort());
        //重置长度
        if (receivePacket != null) {
            receivePacket.setLength(BUFFER);
        }
    }
    @Override
    public void sendMsg(byte[] msg) throws Exception {
        if (msg == null) {
            msg = new byte[1];
        }
        InetAddress serverAddress = InetAddress.getByName(ip);
        final DatagramPacket sendPacket = new DatagramPacket(msg, msg.length, serverAddress, port);
        if (sendPort < 0) {
            final DatagramSocket sendSocket = new DatagramSocket();
            sendSocket.send(sendPacket);
            sendSocket.close();
        } else if (sendPort == monitorPort) {
            mSocket.send(sendPacket);
        } else {
            final DatagramSocket sendSocket = new DatagramSocket(sendPort);
            sendSocket.send(sendPacket);
            sendSocket.close();
        }
    }
    @Override
    public void onConnectStatus(int status) {
        ThreadToolUtils.getInstance().runOnUiThread(new Runnable() {
            @Override
            public void run() {
                final List<ConnectStatusListener> list = getOptions().getConnectStatusListener();
                if (list != null && !list.isEmpty()) {
                    for (ConnectStatusListener listener : list) {
                        switch (status) {
                            case ConnectStatus
                                    .CONNECTING:
                                listener.onConnecting();
                                break;
                            case ConnectStatus
                                    .CONNECTED:
                                listener.onConnected();
                                break;
                            case ConnectStatus
                                    .DISCONNECT:
                                listener.onConnectFailed();
                                break;
                        }
                    }
                }
            IHandleMessage handleMessage = getOptions().getHandleMessage();
            if (handleMessage != null) {
                byte[] data = new byte[receivePacket.getLength()];
                System.arraycopy(receivePacket.getData(), 0, data, 0, data.length);
                handleMessage.read(data,receivePacket.getAddress().getHostAddress());
            }
        });
        } catch (Exception e) {
        }
    }
    @Override
    public void sendMsg(String ipAddress,int port, byte[] msg) throws Exception {
        if (msg == null) {
            return;
        }
        final DatagramPacket sendPacket = new DatagramPacket(msg, msg.length, InetAddress.getByName(ipAddress), port);
        mSocket.send(sendPacket);
    }
}