socket长连接工具类:
package com.github.jasonhancn.tvcursor;import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.widget.Toast;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;public class ServiceSocket implements Runnable {private final int port;private final List<ClientSocket> clientSockets = new CopyOnWriteArrayList<>();public ServiceSocket(int port) {this.port = port;new Thread(this).start();}public void send(String msg) {List<ClientSocket> removeList = new ArrayList<>();for (ClientSocket item : clientSockets) {boolean send = item.send(msg);if (!send) {removeList.add(item);}}clientSockets.removeAll(removeList);}@Overridepublic void run() {ServerSocket serverSocket = null;try {serverSocket = new ServerSocket(port);Log.i("jason_log_main", "run: enter receive client");while (true) {Socket accept = serverSocket.accept();Log.i("jason_log_main", "run: get socket client:" + accept.getInetAddress().getHostAddress());ClientSocket clientSocket = new ClientSocket(accept);clientSockets.add(clientSocket);}} catch (Exception e) {e.printStackTrace();Log.i("jason_log_main", "run: error receive client:" + e.getMessage());} finally {if (serverSocket != null && !serverSocket.isClosed()) {try {serverSocket.close();} catch (IOException e) {e.printStackTrace();}}}}private static class ClientSocket implements Runnable {private Socket socket;private PrintWriter writer;public ClientSocket(Socket socket) {this.socket = socket;new Thread(this).start();}public boolean send(String msg) {if (writer != null) {writer.println(msg);return true;} else {Log.i("jason_log_main", "send: error for server");return false;}}@Overridepublic void run() {try {BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));writer = new PrintWriter(socket.getOutputStream(), true);while (true) {// 读取客户端消息String inputLine = reader.readLine();Log.i("jason_log_main", "run: server receiver:" + inputLine);if (inputLine == null) {break;}if ("heart".equals(inputLine)) {// 回复客户端消息writer.println("server_heart_receive");}}} catch (Exception e) {e.printStackTrace();Log.i("jason_log_main", "run: server client error:" + e.getMessage());} finally {if (socket != null && !socket.isClosed()) {try {socket.close();} catch (IOException e) {e.printStackTrace();}}socket = null;writer = null;}}}public static class OtherClient implements Runnable {private String ip;private int port;private PrintWriter writer;public OtherClient(String ip, int port) {this.ip = ip;this.port = port;new Thread(this).start();}public boolean send(String msg) {if (writer != null) {writer.println(msg);return true;} else {Log.i("jason_log_main", "send: error");return false;}}@Overridepublic void run() {Socket socket = null;try {socket = new Socket();socket.connect(new InetSocketAddress(ip, port));writer = new PrintWriter(socket.getOutputStream(), true);BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));Log.i("jason_log_main", "run: enter client looper");heartBreak();while (true) {String responseLine = reader.readLine();Log.i("jason_log_main", "run: client receive:" + responseLine);if (responseLine == null) {break;}if ("toast".equals(responseLine)) {new Handler(Looper.getMainLooper()).post(() -> Toast.makeText(SocketText.context, "接受勒", Toast.LENGTH_LONG).show());}}} catch (Exception e) {e.printStackTrace();Log.i("jason_log_main", "run: client error:" + e.getMessage());} finally {if (socket != null && !socket.isClosed()) {try {socket.close();} catch (Exception e) {e.printStackTrace();}}writer = null;try {Thread.sleep(6000);} catch (InterruptedException e) {e.printStackTrace();}new Thread(this).start();Log.i("jason_log_main", "run: start new looper for client");}}private void heartBreak() {new Thread(() -> {while (true) {try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}if (!send("heart")) {break;}}}).start();}}
}