2011-01-16 23 views
0

我需要有一個「穩定」的連接到服務器。需要「穩定」的TCP連接到服務器

  1. 客戶端每隔5(10,N)秒嘗試連接到服務器。

  2. 連接成功後,客戶端從服務器接收數據。

  3. 如果發生服務中斷(例如服務器關閉),請轉至步驟#1。

我怎麼測試:

  1. 我啓動服務器

  2. 我啓動客戶端(以確保客戶端從服務器獲取數據)

  3. 我停止服務器

  4. 我等待大約200次客戶端嘗試連接到服務器。

  5. 我重新啓動服務器。

服務器發送數據,但客戶端沒有得到它。 socket.connect(...)已經成功,但是 socket.getInputStream().read(byte[])不是:上的Thread塊。

如果我取消這條線:

//socket.setSoTimeout(500); 

然後input.read(..)拋出一個TimeoutException

但服務器從客戶端接收數據。

我的錯在哪裏? 謝謝。客戶端代碼

部分:

private void initSocket() { 
    try { 
     if (socket == null || socket.isClosed() == true 
       || socket.isConnected() == false) { 
      socket = new Socket(); 
      // socket.setSoTimeout(500); 
      InetSocketAddress socketAddress = new InetSocketAddress("192.168.1.3" 
        , 12344); 
      notifyDataListener(4); 
      socket.connect(socketAddress, 500); 
      notifyDataListener(5); 
     } 
    } catch (Throwable t) { 
     System.err.println(t); 
    } 
} 

private void closeSocket() { 
    try { 
     if (socket != null && socket.isClosed() == false) { 
      socket.close(); 
     } 
    } catch (Throwable t) { 
     System.err.println(t); 
    } 
} 

private byte[] buffer = new byte[1024]; 

public void run() { 
    while (isActive) { 
     try { 
      notifyDataListener(1); 
      initSocket(); 
      InputStream input = socket.getInputStream(); 
      int length = input.read(buffer); 
      if (length < 0) { 
       throw new EOFException("Was got -1"); 
      } 
      notifyDataListener(2); 
     } catch (Throwable t) { 
      closeSocket(); 
      notifyDataListener(3); 
      try { 
       Thread.sleep(100); 
      } catch (InterruptedException ie) { 
      } 
     } 
    } 
} 

在J2SE相同的代碼工作正常。連接修復多次錯誤嘗試後。 看起來Android有限制套接字(FileDescriptior?),接受它們,但不會在發佈之後。

+0

我試過你的代碼,它在我的設備上正常工作(當然使用另一個服務地址)。 – Shlublu

回答

0

您可能會用完文件描述符,我敢肯定,android上的限制比典型的桌面配置要低得多,但具體的值會有所不同。

通過編寫代碼的方式,套接字將一直存在,直到其垃圾收集爲止,另外在某些平臺上,OS級套接字不會立即關閉,而是會暫停一段時間以清理所有掛起的數據。

你應該做的第一件事是將你的socket.close()代碼移動到finally {}語句,這將立即釋放套接字而不是等待垃圾收集。