1. 程式人生 > >sokcet 斷開重連問題

sokcet 斷開重連問題

   socket伺服器已經斷開而主專案這邊完全不知道,如何判斷遠端伺服器是否已經斷開連線,如果斷開那麼需要重新連線。 

   首先想到socket類的方法isClosed()isConnected()isInputStreamShutdown()、 isOutputStreamShutdown()等,但經過試驗並檢視相關文件,這些方法都是本地端的狀態,無法判斷遠端是否已經斷開連線。 

   然後想到是否可以通過OutputStream傳送一段測試資料,如果傳送失敗就表示遠端已經斷開連線,類似ping,但是這樣會影響到正常的輸出資料,遠端無法把正常資料和測試資料分開。 

    解決方法: 使用sendUrgentData

,檢視文件後得知它會往輸出流傳送一個位元組的資料,只要對方SocketSO_OOBINLINE屬性沒有開啟,就會 自動捨棄這個位元組,而SO_OOBINLINE屬性預設情況下就是關閉的。

我的重連類,需要拿來就能用。

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();
 }
}