用于局域网通信的基于udp协议的工具类。具备发送关闭功能。
直接上代码:
package com.example.testapp;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.text.TextUtils;
import android.util.Log;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.nio.ByteBuffer;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class UdpSocketUtils extends Thread {
private static final int BROADCAST_PORT = 9526;
private static final String TAG = "udp_socket_utils";
private DatagramSocket socket;
private OnUdpListener onUdpListener;
private boolean isRunning = true;
private final ExecutorService service = Executors.newSingleThreadExecutor();
public void setOnUdpListener(OnUdpListener onUdpListener) {
this.onUdpListener = onUdpListener;
}
public interface OnUdpListener {
void onBuffer(byte[] bytes);
void onRelease();
}
public void release() {
Log.i(TAG, "release: enter is wait: socket:" + socket);
if (socket == null || !isRunning) {
Log.i(TAG, "release: again enter");
return;
}
isRunning = false;
if (onUdpListener != null) {
onUdpListener.onRelease();
onUdpListener = null;
}
// cancel task
try {
List<Runnable> pendingTask = service.shutdownNow();
Log.i(TAG, "release: cancel count:" + pendingTask.size());
} catch (Exception e) {
Log.i(TAG, "release: error:" + e.getMessage());
}
// release socket
if (socket != null) {
try {
socket.close();
} catch (Exception e) {
Log.e(TAG, "release: error:" + e.getMessage(), e);
}
socket = null;
}
Log.i(TAG, "release: finish");
}
public void sendInner(byte[] buf, String ip) {
if (buf == null || buf.length < 4 || !isRunning) {
Log.i(TAG, "sendInner: len less four");
return;
}
service.execute(() -> {
try {
DatagramPacket sendPacket = new DatagramPacket(buf, buf.length);
sendPacket.setAddress(InetAddress.getByName(ip));
sendPacket.setPort(BROADCAST_PORT);
socket.send(sendPacket);
} catch (IOException e) {
e.printStackTrace();
Log.i(TAG, "sendInner: error:" + e.getMessage());
}
});
}
public void waitSelf() {
try {
join();
} catch (Exception e) {
Log.i(TAG, "waitSelf: error:" + e.getMessage());
}
Log.i(TAG, "waitSelf: is all end");
}
@Override
public void run() {
super.run();
int bufferMaxSize = 4096;
byte[] by = new byte[bufferMaxSize];
try {
socket = new DatagramSocket(BROADCAST_PORT);
socket.setBroadcast(true);
while (isRunning) {
try {
// receive data
DatagramPacket receivePacket = new DatagramPacket(by, by.length);
// Join thread
socket.receive(receivePacket);
// receive package
byte[] buffer = new byte[receivePacket.getLength()];
System.arraycopy(receivePacket.getData(), 0, buffer, 0, buffer.length);
String ip = receivePacket.getAddress().getHostAddress();
receiveData(buffer);
Log.i(TAG, "run: other ip:" + ip + "; data len:" + buffer.length);
} catch (Exception e) {
e.printStackTrace();
Log.i(TAG, "run: error:" + e.getMessage());
}
}
} catch (Exception e) {
e.printStackTrace();
Log.i(TAG, "run: error:" + e.getMessage());
}
release();
}
private void receiveData(byte[] buffer) {
if (onUdpListener != null && isRunning) {
onUdpListener.onBuffer(buffer);
}
}
public void sendBroadCast(Context context, String msg) {
String ipAddress = getIPAddress(context);
Log.i(TAG, "sendBroadCast: ip origin:" + ipAddress);
if (TextUtils.isEmpty(ipAddress) || ipAddress.length() < 8) {
return;
}
try {
int index = ipAddress.lastIndexOf(".");
ipAddress = ipAddress.substring(0, index) + ".255";
Log.i(TAG, "sendBroadCast: send ip:" + ipAddress);
sendInner(msg.getBytes(), ipAddress);
} catch (Exception e) {
e.printStackTrace();
}
}
// ------------------------------------------------ tools begin
public String getIPAddress(Context context) {
String ipAddress = null;
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
Network network = connectivityManager.getActiveNetwork();
NetworkCapabilities networkCapabilities = connectivityManager.getNetworkCapabilities(network);
if (networkCapabilities != null && networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
ipAddress = getIPAddressFromWifiManager(context);
}
return ipAddress;
}
private String getIPAddressFromWifiManager(Context context) {
WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
int ipAddress = wifiInfo.getIpAddress();
return formatIpAddress(ipAddress);
}
public static String formatIpAddress(int ip) {
try {
// 将整数形式的 IP 地址转换为字节数组
byte[] bytes = ByteBuffer.allocate(4).putInt(ip).array();
// 由于 InetAddress.getByAddress() 需要网络字节顺序(big-endian),我们需要反转字节数组
for (int i = 0; i < bytes.length / 2; i++) {
byte temp = bytes[i];
bytes[i] = bytes[bytes.length - i - 1];
bytes[bytes.length - i - 1] = temp;
}
// 获取 InetAddress 对象并返回字符串形式的 IP 地址
InetAddress inetAddress = InetAddress.getByAddress(bytes);
return inetAddress.getHostAddress();
} catch (Exception e) {
// UnknownHostException 是一个检查异常,你可以选择记录或者处理这个异常
e.printStackTrace();
return null;
}
}
}