sokcet 斷開重連問題
阿新 • • 發佈:2019-01-06
socket伺服器已經斷開而主專案這邊完全不知道,如何判斷遠端伺服器是否已經斷開連線,如果斷開那麼需要重新連線。
首先想到socket類的方法isClosed()、isConnected()、isInputStreamShutdown()、 isOutputStreamShutdown()等,但經過試驗並檢視相關文件,這些方法都是本地端的狀態,無法判斷遠端是否已經斷開連線。
然後想到是否可以通過OutputStream傳送一段測試資料,如果傳送失敗就表示遠端已經斷開連線,類似ping,但是這樣會影響到正常的輸出資料,遠端無法把正常資料和測試資料分開。 ,檢視文件後得知它會往輸出流傳送一個位元組的資料,只要對方Socket的SO_OOBINLINE屬性沒有開啟,就會 自動捨棄這個位元組,而SO_OOBINLINE屬性預設情況下就是關閉的。
首先想到socket類的方法isClosed()、isConnected()、isInputStreamShutdown()、 isOutputStreamShutdown()等,但經過試驗並檢視相關文件,這些方法都是本地端的狀態,無法判斷遠端是否已經斷開連線。
然後想到是否可以通過OutputStream傳送一段測試資料,如果傳送失敗就表示遠端已經斷開連線,類似ping,但是這樣會影響到正常的輸出資料,遠端無法把正常資料和測試資料分開。
解決方法: 使用sendUrgentData
我的重連類,需要拿來就能用。
public class IsAgainConnect implements Runnable { private static final boolean CONNECT = true; private static final int WAIT_TIME = 5000; private WifiLinking wifiLinking = null; public void run() { // TODO Auto-generated method stub reunion(); } public IsAgainConnect(WifiLinking wifiLinking) { this.wifiLinking = wifiLinking; initiate(); } // run方法 private void reunion() { while (CONNECT) { holdTime(WAIT_TIME); } } // 等待時間 private void holdTime(int time) { try { Thread.sleep(time); } catch (InterruptedException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } sendTestData(); } // 傳送測試資料 private void sendTestData() { try { if (wifiLinking.socket != null) { wifiLinking.socket.sendUrgentData(0xFF); } } catch (IOException e) { handle(); } } // 異常處理 private void handle() { try { Looper.prepare(); wifiLinking.socket = new Socket(WifiLinking.SERVER_IP,WifiLinking.SERVER_PORT); Toast.makeText(wifiLinking.context, "已重新與伺服器連線!",Toast.LENGTH_LONG).show(); } catch (Exception e1) { Toast.makeText(wifiLinking.context, "與伺服器無連線!", Toast.LENGTH_LONG).show(); initiate(); } Looper.loop(); } // 啟動重連執行緒 private void initiate() { Thread isAgainThread = new Thread(IsAgainConnect.this); isAgainThread.start(); } }