簡體   English   中英

客戶端重新連接java套接字

[英]client reconnect java socket

好的,我需要編寫一個能夠檢測客戶端和服務器之間連接的客戶端......一旦服務器關閉並恢復我的客戶端需要能夠將其連接回服務器......但我真的不是確定怎么做...如果可能的話有什么幫助嗎?

 public TEST(String serverIP, int serverPort){
    Log("Connection to the Server....");
    try{
        socket = new Socket(serverIP, serverPort);
        Log("Connected to the server : "+socket);
        start();
    } catch(UnknownHostException uhe){
        System.out.println("Unknown Host: "+ uhe.getMessage());
    } catch (IOException ioe){
        System.out.println("IO Exception: "+ioe.getMessage());
    }

    String readline = "";

    streamOutput.println("TRY test");

    while(true){
        try{
            readline = streamInput.readLine();
            System.out.println(readline);
        } catch (IOException ioe){
            System.out.println("Error in sending: "+ioe.getMessage());
            return;
        }
    }
}

上面是我的客戶端代碼,用於在編譯后連接到服務器...

知道連接已關閉的唯一方法是嘗試通過線路發送數據。 連接不會自動測試打開/關閉狀態。 如果要檢查關閉的連接並重新連接,則必須從一個連接到另一個發送心跳信號。 通常,它只是一個特殊的字節或微小的消息,告訴對方“我還在這里”

但是,根據您的應用程序,您可能不需要它。 您的應用程序的雙方都啟動消息嗎? 或者它是一個 RMI 風格的應用程序? 服務器在哪里只偵聽請求?

也許是這樣的?

    class Client {
        private Socket socket;
        private boolean tryToReconnect = true;
        private final Thread heartbeatThread;
        private long heartbeatDelayMillis = 5000;

        public Client(final String server, final int port) {
            connect(server, port);
            heartbeatThread = new Thread() {
                public void run() {
                    while (tryToReconnect) {
                        //send a test signal
                        try {
                            socket.getOutputStream().write(666);
                            sleep(heartbeatDelayMillis);
                        } catch (InterruptedException e) {
                            // You may or may not want to stop the thread here
                            // tryToReconnect = false;
                        } catch (IOException e) {
                            logger.warn("Server is offline");
                            connect(server, port);
                        }
                    }
                };
            };
            heartbeatThread.start();
        }

        private void connect(String server, int port){
            try {
                socket = new Socket(server, port);
            } catch (UnknownHostException e) {
                logger.error(e, e);
            } catch (IOException e) {
                logger.error(e, e);
            }
        }

        public void shutdown() {
            tryToReconnect = false;
        }
    }

這是一個非常常見的問題(需要知道管道何時損壞)並且該方法中的一個答案是正確的,即客戶端將需要(定期)“檢查”套接字以查看它是否已關閉。 服務器不會通知客戶端套接字已關閉,並且確實不能,因為它已關閉。 客戶端服務器之間的防火牆、代理等可能在建立連接后的任何時候終止或以其他方式阻止一個或兩個方向的套接字通信。

首先,如果您已經完成了大量套接字編程(在“C”或 Java 等中)……您將看到“試圖在損壞的管道上寫入”類型的錯誤/異常。 客戶端嘗試在關閉的套接字(剛剛檢測到已關閉)上寫入(發送)數據時,這是一個 I/O 類錯誤。

所以答案在於管理Socket創建層之上的socket。

也就是說,客戶端上的線程需要通過發送數據(定期發送到服務器作為一種“ping”來檢查管道損壞情況)來監視套接字,然后銷毀(清理)並重新如果發生 I/O 錯誤,則創建套接字(沖洗並重復)。

請注意,如果客戶端可以確保服務器對給定的“ping”做出預期和一致(和及時)的響應,則更復雜的雙向邏輯會更好。 這將具體確認雙向流量正在流動。 否則防火牆可能會關閉一個方向的流量,而客戶端認為它仍在與服務器“交談”(服務器很可能正在接收數據但無法傳輸回客戶端 - 可能導致它在不活動超時時終止連接) .

似乎您不需要自己實現聽節拍。 它們已經在大多數 TCP 實現中實現。

如果您的連接是 TCP,則您要查找的內容位於較低的層中。 看看 TCP KeepAlive。


這些鏈接可能會有所幫助:

  1. 如何測試 TCP KeepAlive? .
  2. TCP 保活概述

當您的客戶端捕獲到SocketException它應該進入它的tryToReconnect狀態。 現在它以某個時間間隔(例如,1 秒可能更長,取決於服務器)探測服務器。 確保您實現了一些邏輯以在不再需要時停止它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM