该代码为开发者提供一个框架,用于在Android应用中建立Socket连接、读取数据,并处理连接过程中的异常和线程同步问题。(可用于常用的WIFI通信)
import android.util.Log;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class WifiController {
private static final String TAG = "SocketUtil";
private static Socket mSocket;
private static SocketConnectThread socketConnectThread;
private static StringBuffer stringBuffer;
public WifiController() {} // 私有构造函数,防止外部实例化
private static boolean isConnecting = false; // 添加一个布尔变量来跟踪连接状态
public static class SocketConnectThread implements Callable<Boolean> {
private final String ip;
private final int port;
private final int timeout; // 添加一个超时时间参数
public SocketConnectThread(String ip, int port, int timeout) {
this.ip = ip;
this.port = port;
this.timeout = timeout;
}
/***
* 是一个Java的Callable接口的call方法实现
* 它用于在并发环境中执行一个可能返回结果或抛出异常的任务。
* 任务是尝试连接到指定的IP地址和端口,并在成功连接后启动一个读取方法(用于接收从服务器发送的数据)。
* @return
*/
@Override
public Boolean call() {
try {
mSocket = new Socket();
mSocket.connect(new InetSocketAddress(ip, port), timeout); // 开始连接并设置连接超时时间
//检查连接状态
if (mSocket.isConnected()) {
startReader(); // 开始接收信息
Log.i(TAG, "startReader: 启动startReader()");
}
return true;
} catch (IOException e) {
Log.e(TAG, "Socket connection failed: " + e.getMessage());
return false;
}
}
}
/**
* 开始连接
* @param ip 设定IP
* @param port 设定端口
* @param timeout 设定超时
* @return 如果连接成功,返回true;否则返回false
*/
public static boolean connect(String ip, int port, int timeout) {
//正在连接中
if (isConnecting) {
Log.w(TAG, "Socket connection already in progress");
return false;
}
isConnecting = true;
ExecutorService executor = Executors.newSingleThreadExecutor(); // 创建一个单线程执行器
Future<Boolean> future = executor.submit(new SocketConnectThread(ip, port, timeout)); // 提交 SocketConnectThread 任务并获取 Future 对象
try {
boolean result = future.get(); // 等待异步任务执行完成并获取结果
isConnecting = false; // 连接完成,设置连接状态为 false,以不在(尝试)连接状态
return result; // 返回连接结果
} catch (InterruptedException | ExecutionException e) {
Log.e(TAG, "Connection failed: " + e.getMessage());
if (mSocket != null && !mSocket.isClosed()) {
try {
mSocket.close(); // 连接失败,关闭Socket
} catch (IOException ex) {
ex.printStackTrace();
}
}
isConnecting = false; // 连接失败,设置连接状态为 false,以不在(尝试)连接状态
return false; // 返回 false,表示连接失败
} finally {
executor.shutdown();
}
}
/***
* 发送信息
* @param msg 需要发送的信息内容
*/
public static void sendMessage(String msg) {
if (mSocket == null || !mSocket.isConnected()) {
Log.w(TAG, "Socket not connected, cannot send message");
return;
}
new Thread(() -> {
try {
OutputStream outputStream = mSocket.getOutputStream();
outputStream.write(msg.getBytes());
} catch (IOException e) {
Log.e(TAG, "Failed to send message: " + e.getMessage());
}
}).start();
}
/***
* 接收信息
*/
private static void startReader() {
new Thread(() -> {
try {
//使用一个缓冲区来存储接收到的数据,并通过String的构造函数将字节数组转换为字符串。
byte[] buffer;
int length;
String data;
InputStream inputStream = mSocket.getInputStream();
while (mSocket.isConnected()) {
buffer = new byte[1024];
length = inputStream.read(buffer);
data = new String(buffer, 0, length);
Log.i(TAG, "startReader: 收到的消息为:" + data);
}
} catch (IOException e) {
Log.e(TAG, "Socket read error: " + e.getMessage());
}
}).start();
}
/***
* 关闭连接
*/
public static void closeSocket() {
if (mSocket != null) {
try {
mSocket.close();
} catch (IOException e) {
Log.e(TAG, "Failed to close socket: " + e.getMessage());
} finally {
mSocket = null;
}
}
}
}