2023-08-15 05:18:25 +00:00
|
|
|
|
package com.bg7yoz.ft8cn.flex;
|
|
|
|
|
/**
|
|
|
|
|
* 简单的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 RadioUdpClient {
|
|
|
|
|
private static final String TAG = "RadioUdpSocket";
|
2024-01-24 07:09:36 +00:00
|
|
|
|
private final int MAX_BUFFER_SIZE = 1024*4;
|
2023-08-15 05:18:25 +00:00
|
|
|
|
private DatagramSocket sendSocket;
|
|
|
|
|
private int port;
|
|
|
|
|
private boolean activated = false;
|
|
|
|
|
private OnUdpEvents onUdpEvents = null;
|
|
|
|
|
private final ExecutorService sendDataThreadPool = Executors.newCachedThreadPool();
|
|
|
|
|
private final ExecutorService receiveThreadPool = Executors.newCachedThreadPool();
|
|
|
|
|
private final SendDataRunnable sendDataRunnable=new SendDataRunnable(this);
|
|
|
|
|
private final ReceiveRunnable receiveRunnable=new ReceiveRunnable(this);
|
|
|
|
|
|
|
|
|
|
public RadioUdpClient(int port) {
|
|
|
|
|
this.port = port;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public synchronized void sendData(byte[] data, String ip,int port) throws UnknownHostException {
|
|
|
|
|
if (!activated) return;
|
|
|
|
|
//Log.e(TAG, "sendData: "+byteToStr(data) );
|
|
|
|
|
//Log.e(TAG, String.format("sendData: ip: %s,port:%d ",ip,port) );
|
|
|
|
|
InetAddress address = InetAddress.getByName(ip);
|
|
|
|
|
sendDataRunnable.data=data;
|
|
|
|
|
sendDataRunnable.address=address;
|
|
|
|
|
sendDataRunnable.port=port;
|
|
|
|
|
sendDataThreadPool.execute(sendDataRunnable);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static class SendDataRunnable implements Runnable{
|
|
|
|
|
byte[] data;
|
|
|
|
|
InetAddress address;
|
|
|
|
|
int port;
|
|
|
|
|
RadioUdpClient client;
|
|
|
|
|
|
|
|
|
|
public SendDataRunnable(RadioUdpClient client) {
|
|
|
|
|
this.client = client;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void run() {
|
|
|
|
|
DatagramPacket packet = new DatagramPacket(data, data.length, address,port);
|
|
|
|
|
try {
|
|
|
|
|
client.sendSocket.send(packet);
|
|
|
|
|
} catch (IOException e) {
|
|
|
|
|
e.printStackTrace();
|
|
|
|
|
Log.e(TAG, "run: " + e.getMessage());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public boolean isActivated() {
|
|
|
|
|
return activated;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public synchronized void setActivated(boolean activated) throws SocketException {
|
|
|
|
|
this.activated = activated;
|
|
|
|
|
if (activated) {//通过activated判断是否结束接收线程,并清空sendSocket指针
|
|
|
|
|
sendSocket = new DatagramSocket(null);//绑定的端口号随机
|
|
|
|
|
sendSocket.bind(new InetSocketAddress(port));
|
|
|
|
|
receiveData();
|
|
|
|
|
}else {
|
|
|
|
|
if (sendSocket!=null){
|
|
|
|
|
sendSocket.close();
|
|
|
|
|
try {
|
|
|
|
|
Thread.sleep(100);
|
|
|
|
|
} catch (InterruptedException e) {
|
|
|
|
|
e.printStackTrace();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void receiveData() {
|
|
|
|
|
receiveThreadPool.execute(receiveRunnable);
|
|
|
|
|
}
|
|
|
|
|
private static class ReceiveRunnable implements Runnable{
|
|
|
|
|
RadioUdpClient client;
|
|
|
|
|
|
|
|
|
|
public ReceiveRunnable(RadioUdpClient client) {
|
|
|
|
|
this.client = client;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void run() {
|
|
|
|
|
while (client.activated) {
|
2024-01-24 07:09:36 +00:00
|
|
|
|
|
2023-08-15 05:18:25 +00:00
|
|
|
|
byte[] data = new byte[client.MAX_BUFFER_SIZE];
|
|
|
|
|
DatagramPacket packet = new DatagramPacket(data, data.length);
|
|
|
|
|
try {
|
|
|
|
|
client.sendSocket.receive(packet);
|
|
|
|
|
if (client.onUdpEvents != null) {
|
|
|
|
|
byte[] temp = Arrays.copyOf(packet.getData(), packet.getLength());
|
2024-01-24 07:09:36 +00:00
|
|
|
|
|
2023-08-15 05:18:25 +00:00
|
|
|
|
client.onUdpEvents.OnReceiveData(client.sendSocket, packet, temp);
|
2024-01-24 07:09:36 +00:00
|
|
|
|
|
|
|
|
|
|
2023-08-15 05:18:25 +00:00
|
|
|
|
}
|
|
|
|
|
} catch (IOException e) {
|
|
|
|
|
e.printStackTrace();
|
|
|
|
|
Log.e(TAG, "receiveData: error:" + e.getMessage());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
Log.e(TAG, "udpClient: is exit!");
|
|
|
|
|
client.sendSocket.close();
|
|
|
|
|
client.sendSocket = null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
public void setOnUdpEvents(OnUdpEvents onUdpEvents) {
|
|
|
|
|
this.onUdpEvents = onUdpEvents;
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-24 07:09:36 +00:00
|
|
|
|
public interface OnUdpEvents {
|
2023-08-15 05:18:25 +00:00
|
|
|
|
void OnReceiveData(DatagramSocket socket, DatagramPacket packet, byte[] data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public int getPort() {
|
|
|
|
|
if (sendSocket!=null){
|
|
|
|
|
return sendSocket.getLocalPort();
|
|
|
|
|
}else {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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();
|
|
|
|
|
}
|
|
|
|
|
}
|