kopia lustrzana https://github.com/N0BOY/FT8CN
227 wiersze
7.6 KiB
Java
227 wiersze
7.6 KiB
Java
package com.bg7yoz.ft8cn.icom;
|
||
/**
|
||
* 简单封装的udp协议处理
|
||
* @author BGY70Z
|
||
* @date 2023-03-20
|
||
*/
|
||
|
||
import android.util.Log;
|
||
|
||
import java.io.IOException;
|
||
import java.net.DatagramPacket;
|
||
import java.net.DatagramSocket;
|
||
import java.net.InetAddress;
|
||
import java.net.InetSocketAddress;
|
||
import java.net.SocketException;
|
||
import java.net.UnknownHostException;
|
||
import java.util.Arrays;
|
||
import java.util.concurrent.ExecutorService;
|
||
import java.util.concurrent.Executors;
|
||
|
||
public class IcomUdpClient {
|
||
private static final String TAG = "RadioUdpSocket";
|
||
|
||
|
||
private final int MAX_BUFFER_SIZE = 1024 *2;
|
||
private DatagramSocket sendSocket;
|
||
//private int remotePort;
|
||
private int localPort=-1;
|
||
private boolean activated = false;
|
||
private OnUdpEvents onUdpEvents = null;
|
||
private final ExecutorService doReceiveThreadPool = Executors.newCachedThreadPool();
|
||
private DoReceiveRunnable doReceiveRunnable=new DoReceiveRunnable(this);
|
||
private final ExecutorService sendDataThreadPool = Executors.newCachedThreadPool();
|
||
private SendDataRunnable sendDataRunnable=new SendDataRunnable(this);
|
||
|
||
public IcomUdpClient() {//本地端口随机
|
||
localPort=-1;
|
||
}
|
||
public IcomUdpClient(int localPort) {//如果localPort==-1,本地端口随机
|
||
this.localPort=localPort;
|
||
}
|
||
|
||
public void sendData(byte[] data, String ip,int port) throws UnknownHostException {
|
||
if (!activated) return;
|
||
|
||
InetAddress address = InetAddress.getByName(ip);
|
||
sendDataRunnable.address=address;
|
||
sendDataRunnable.data=data;
|
||
sendDataRunnable.port=port;
|
||
sendDataThreadPool.execute(sendDataRunnable);
|
||
// new Thread(new Runnable() {
|
||
// @Override
|
||
// public void run() {
|
||
// DatagramPacket packet = new DatagramPacket(data, data.length, address, port);
|
||
// synchronized (this) {
|
||
// try {
|
||
// sendSocket.send(packet);
|
||
// } catch (IOException e) {
|
||
// e.printStackTrace();
|
||
// Log.e(TAG, "IComUdpClient: " + e.getMessage());
|
||
// if (onUdpEvents!=null){
|
||
// onUdpEvents.OnUdpSendIOException(e);
|
||
// }
|
||
// }
|
||
// }
|
||
// }
|
||
// }).start();
|
||
}
|
||
private static class SendDataRunnable implements Runnable{
|
||
byte[] data;
|
||
int port;
|
||
InetAddress address;
|
||
IcomUdpClient client;
|
||
|
||
public SendDataRunnable(IcomUdpClient client) {
|
||
this.client = client;
|
||
}
|
||
|
||
@Override
|
||
public void run() {
|
||
DatagramPacket packet = new DatagramPacket(data, data.length, address, port);
|
||
synchronized (this) {
|
||
try {
|
||
client.sendSocket.send(packet);
|
||
} catch (IOException e) {
|
||
e.printStackTrace();
|
||
Log.e(TAG, "IComUdpClient: " + e.getMessage());
|
||
if (client.onUdpEvents!=null){
|
||
client.onUdpEvents.OnUdpSendIOException(e);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
public boolean isActivated() {
|
||
return activated;
|
||
}
|
||
|
||
public synchronized void setActivated(boolean activated) throws SocketException {
|
||
this.activated = activated;
|
||
if (activated) {//通过activated判断是否结束接收线程,并清空sendSocket指针
|
||
sendSocket = new DatagramSocket();
|
||
//new DatagramSocket(null);//绑定的端口号随机
|
||
sendSocket.setReuseAddress(true);
|
||
if (localPort!=-1) {//绑定指定的本机端口
|
||
sendSocket.bind(new InetSocketAddress(localPort));
|
||
}
|
||
|
||
//更新一下本地端口值
|
||
localPort=sendSocket.getLocalPort();
|
||
Log.e(TAG, "openUdpPort: " + sendSocket.getLocalPort());
|
||
//Log.e(TAG, "openUdpIp: " + sendSocket.getLocalAddress());
|
||
|
||
|
||
receiveData();
|
||
} else {
|
||
if (sendSocket != null) {
|
||
sendSocket.close();
|
||
try {
|
||
Thread.sleep(100);
|
||
} catch (InterruptedException e) {
|
||
e.printStackTrace();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
private void receiveData() {
|
||
doReceiveThreadPool.execute(doReceiveRunnable);
|
||
// new Thread(new Runnable() {
|
||
// @Override
|
||
// public void run() {
|
||
// while (activated) {
|
||
// byte[] data = new byte[MAX_BUFFER_SIZE];
|
||
// DatagramPacket packet = new DatagramPacket(data, data.length);
|
||
// try {
|
||
// sendSocket.receive(packet);
|
||
// if (onUdpEvents != null) {
|
||
// byte[] temp = Arrays.copyOf(packet.getData(), packet.getLength());
|
||
// onUdpEvents.OnReceiveData(sendSocket, packet, temp);
|
||
// }
|
||
// //Log.d(TAG, "receiveData:host ip: " + packet.getAddress().getHostName());
|
||
// } catch (IOException e) {
|
||
// e.printStackTrace();
|
||
// Log.e(TAG, "receiveData: error:" + e.getMessage());
|
||
// }
|
||
//
|
||
// }
|
||
// Log.e(TAG, "udpClient: is exit!");
|
||
// sendSocket.close();
|
||
// sendSocket = null;
|
||
// }
|
||
// }).start();
|
||
|
||
}
|
||
|
||
public void setOnUdpEvents(OnUdpEvents onUdpEvents) {
|
||
this.onUdpEvents = onUdpEvents;
|
||
}
|
||
|
||
public interface OnUdpEvents {
|
||
void OnReceiveData(DatagramSocket socket, DatagramPacket packet, byte[] data);
|
||
void OnUdpSendIOException(IOException e);
|
||
}
|
||
|
||
public int getLocalPort() {
|
||
if (sendSocket != null) {
|
||
return sendSocket.getLocalPort();
|
||
} else {
|
||
return 0;
|
||
}
|
||
}
|
||
|
||
public String getLocalIp() {
|
||
if (sendSocket != null) {
|
||
return sendSocket.getLocalAddress().toString();
|
||
} else {
|
||
return "127.0.0.1";
|
||
}
|
||
}
|
||
|
||
public DatagramSocket getSendSocket() {
|
||
return sendSocket;
|
||
}
|
||
|
||
|
||
public static String byteToStr(byte[] data) {
|
||
StringBuilder s = new StringBuilder();
|
||
for (int i = 0; i < data.length; i++) {
|
||
s.append(String.format("%02x ", data[i] & 0xff));
|
||
}
|
||
return s.toString();
|
||
}
|
||
private static class DoReceiveRunnable implements Runnable{
|
||
IcomUdpClient icomUdpClient;
|
||
|
||
public DoReceiveRunnable(IcomUdpClient icomUdpClient) {
|
||
this.icomUdpClient = icomUdpClient;
|
||
}
|
||
|
||
@Override
|
||
public void run() {
|
||
while (icomUdpClient.activated) {
|
||
byte[] data = new byte[icomUdpClient.MAX_BUFFER_SIZE];
|
||
DatagramPacket packet = new DatagramPacket(data, data.length);
|
||
try {
|
||
icomUdpClient.sendSocket.receive(packet);
|
||
if (icomUdpClient.onUdpEvents != null) {
|
||
byte[] temp = Arrays.copyOf(packet.getData(), packet.getLength());
|
||
icomUdpClient.onUdpEvents.OnReceiveData(icomUdpClient.sendSocket, packet, temp);
|
||
}
|
||
//Log.d(TAG, "receiveData:host ip: " + packet.getAddress().getHostName());
|
||
} catch (IOException e) {
|
||
e.printStackTrace();
|
||
Log.e(TAG, "receiveData: error:" + e.getMessage());
|
||
}
|
||
|
||
}
|
||
Log.e(TAG, "udpClient: is exit!");
|
||
icomUdpClient.sendSocket.close();
|
||
icomUdpClient.sendSocket = null;
|
||
}
|
||
}
|
||
|
||
}
|