2015-01-31 27 views
0

所以我有一個帶套接字連接的Client類。當客戶端連接到服務器時,我首先讀取該套接字以獲取有關客戶端的信息。然後,我將客戶端移動到一個擁有所有連接客戶端(發送其信息的客戶端)的表格。然後,我聽新連接的主要套接字是我創建客戶端的地方。問題是我不確定何時以及是否有一個在套接字上讀取的對象被銷燬。我目前的策略是在第二張桌子上放置所有尚未發送信息的客戶端(如果您願意的話,可以使用未連接的客戶端)。一旦客戶發送他的信息,我將他從未連接的表格移動到連接的表格。我真的很討厭這種方法。我只想在accept回調中創建客戶端而不將其添加到表中。一旦接收到信息,客戶端就會將其移動到連接的表格中。用套接字連接破壞Java對象

我目前的執行情況:

myMainChannel.accept(null, new CompletionHandler<AsynchronousSocketChannel,Void>() 
     { 
       public void completed(final AsynchronousSocketChannel ch, void att) 
       { 
        // accept the next connection 
        myMainChannel.accept(null, this); 
        //add client to unconnected table 
        allUnconnectedClients.put(ch, new Client(ch)); 
       } 
       public void failed(Throwable exc, Void att) 
       {      
        exc.printStackTrace(); 
       } 

     }); 

客戶端的構造函數中是第一次讀操作。

id喜歡做的事情就是簡單地創建客戶端而不將它添加到表中。因此,換句話說repalce這樣的:

allUnconnectedClients.put(ch, new Client(ch)); 

與此:

new Client(ch); 

我知道這有點怪異只創建一個局部變量不使用它,但有一個讀超時(在構造函數中),將如果5秒內沒有收到任何東西,請關閉所有設備

+0

糟糕的設計。不要在'accept()'循環中對客戶進行I/O操作。 accept()循環除了接受連接之外不應該做任何事情,否則I/O可能會阻塞下一個客戶端。重新設計這個。 – EJP 2015-01-31 23:30:08

+0

@EJP這是一個異步套接字,所以I/O工作實際上並沒有阻塞任何東西,即使它不是在已完成的回調中以及在客戶端上完成任何實際工作之前調用接受回調。如果需要在接受後立即完成I/O工作,我應該在哪裏做? – Maro 2015-01-31 23:33:58

+0

下定決心。你說構造函數有一個超時讀取。沒有什麼異步的。 – EJP 2015-02-01 00:00:32

回答

0

由於您可能會在任何給定時間等待讀取或寫入,因此您可以在任何給定時間使用接受附件+完成處理程序的read/write methods。你的Client將是附件。 處理程序將負責註冊下一個讀取或寫入回調。如果沒有,那麼客戶端將有資格進行垃圾回收。

認爲它是繼續傳球。

+0

所以如果我通過客戶端作爲附件,那麼它不會被垃圾收集直到有一個失敗或完成? – Maro 2015-02-01 00:11:06