Java Socket通信中怎樣進(jìn)行心跳檢測(cè)

小樊
82
2024-10-16 18:28:20

在Java Socket通信中,進(jìn)行心跳檢測(cè)的目的是為了保持連接的活躍狀態(tài),防止因?yàn)殚L(zhǎng)時(shí)間不通信導(dǎo)致的連接被客戶(hù)端或服務(wù)器端主動(dòng)關(guān)閉。下面是一個(gè)簡(jiǎn)單的心跳檢測(cè)示例:

  1. 服務(wù)器端:
import java.io.*;
import java.net.*;
import java.util.concurrent.*;

public class Server {
    public static void main(String[] args) throws IOException, InterruptedException {
        int port = 12345;
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        ServerSocket serverSocket = new ServerSocket(port);

        while (true) {
            Socket clientSocket = serverSocket.accept();
            executorService.submit(() -> handleClient(clientSocket));
        }
    }

    private static void handleClient(Socket clientSocket) {
        try {
            InputStream inputStream = clientSocket.getInputStream();
            OutputStream outputStream = clientSocket.getOutputStream();

            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
            PrintWriter writer = new PrintWriter(outputStream, true);

            String heartBeatMessage = "HEARTBEAT";
            while (true) {
                // 發(fā)送心跳包
                writer.println(heartBeatMessage);
                Thread.sleep(5000); // 每5秒發(fā)送一次心跳包

                // 讀取客戶(hù)端返回的消息
                String message = reader.readLine();
                if (message != null && message.equals(heartBeatMessage)) {
                    // 收到客戶(hù)端的心跳包,回應(yīng)一個(gè)確認(rèn)消息
                    writer.println("HEARTBEAT_ACK");
                } else {
                    // 沒(méi)有收到心跳包,關(guān)閉連接
                    break;
                }
            }
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        } finally {
            try {
                clientSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
  1. 客戶(hù)端:
import java.io.*;
import java.net.*;
import java.util.concurrent.*;

public class Client {
    public static void main(String[] args) throws IOException, InterruptedException {
        String serverAddress = "localhost";
        int port = 12345;
        Socket socket = new Socket(serverAddress, port);
        ExecutorService executorService = Executors.newFixedThreadPool(10);

        // 啟動(dòng)一個(gè)線(xiàn)程定期發(fā)送心跳包
        executorService.submit(() -> sendHeartBeat(socket));

        BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        String message;
        while ((message = reader.readLine()) != null) {
            System.out.println("Received from server: " + message);
            if (message.equals("HEARTBEAT_ACK")) {
                // 收到服務(wù)器的確認(rèn)消息,繼續(xù)發(fā)送心跳包
                sendHeartBeat(socket);
            }
        }
    }

    private static void sendHeartBeat(Socket socket) throws IOException, InterruptedException {
        OutputStream outputStream = socket.getOutputStream();
        PrintWriter writer = new PrintWriter(outputStream, true);
        String heartBeatMessage = "HEARTBEAT";
        while (true) {
            // 發(fā)送心跳包
            writer.println(heartBeatMessage);
            Thread.sleep(5000); // 每5秒發(fā)送一次心跳包
        }
    }
}

在這個(gè)示例中,服務(wù)器端和客戶(hù)端都會(huì)定期發(fā)送心跳包,以保持連接的活躍狀態(tài)。如果一方在一段時(shí)間內(nèi)沒(méi)有收到心跳包,它會(huì)認(rèn)為連接已經(jīng)斷開(kāi),并關(guān)閉連接。

0