package com.hdl.sdk.socket.client;
|
|
|
import android.util.Log;
|
|
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.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.net.SocketAddress;
|
import java.util.List;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
|
|
/**
|
* Created by Tong on 2021/9/15.
|
* 组播需要android.permission.CHANGE_WIFI_MULTICAST_STATE权限
|
* MulticastSocket
|
*/
|
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);
|
|
/**
|
* @param sendPort -1 表示随机端口
|
*/
|
private UdpClient(String ip, int port, int monitorPort, int sendPort, SocketOptions socketOptions) {
|
this.socketOptions = socketOptions;
|
this.ip = ip;
|
this.port = port;
|
this.sendPort = sendPort;
|
this.monitorPort = monitorPort;
|
this.receiveByte = new byte[BUFFER];
|
}
|
|
public UdpClient(String ip, int port) {
|
this.ip = ip;
|
this.port = port;
|
this.receiveByte = new byte[BUFFER];
|
}
|
|
public static SocketBoot init(String ip, int port, int monitorPort, int sendPort, SocketOptions options) {
|
return new SocketBoot(new UdpClient(ip, port, monitorPort, sendPort, 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 {
|
try {
|
mSocket = SocketPool.getInstance().getUdpSocket(new InetSocketAddress(monitorPort));
|
|
mSocket.setBroadcast(true);
|
mSocket.setReuseAddress(true);
|
isConnect.set(true);
|
if (receivePacket == null) {
|
receivePacket = new DatagramPacket(receiveByte, BUFFER);
|
}
|
} catch (Exception e) {
|
isConnect.set(false);
|
throw e;
|
}
|
|
|
}
|
|
@Override
|
public void disconnect() {
|
if (mSocket != null) {
|
mSocket.close();
|
}
|
isConnect.set(false);
|
}
|
|
@Override
|
public boolean isConnect() {
|
return isConnect.get();
|
}
|
|
@Override
|
public synchronized SocketOptions getOptions() {
|
if (socketOptions == null) {
|
socketOptions = new SocketOptions();
|
}
|
return socketOptions;
|
}
|
|
@Override
|
public void onHandleResponse() throws Exception {
|
if (receivePacket == null || mSocket == null) {
|
return;
|
}
|
try {
|
mSocket.receive(receivePacket);
|
} catch (IOException e) {
|
e.printStackTrace();
|
isConnect.set(false);
|
}
|
if (receivePacket.getLength() == 0) {
|
return;
|
}
|
//排除自己发出去的
|
try {
|
if (IpUtils.isLocalIpAddress( receivePacket.getAddress().getHostAddress()))
|
return;
|
} catch (Exception ignored) {
|
|
}
|
|
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);
|
}
|
final String receive = new String(receivePacket.getData(), 0, receivePacket.getLength());
|
|
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;
|
}
|
}
|
}
|
}
|
});
|
}
|
}
|