2013-01-22 75 views
0

我試圖用Java編寫簡單的在線狀態顯示器爲我的Communicator客戶端 - 服務器。當有人連接它時,會在我的JList中在線顯示新成員。簡單。我有一個名爲「容器」的類(顧名思義)包含對List對象和消息對象的引用。我的清單是一個簡單的地圖,其中key是每個用戶的唯一ID,String是他的暱稱。該地圖在列表對象中是一個字段。然後,我將這個序列化的對象發送給客戶端。問題是,當我有兩個客戶端時,第一個連接到服務器的人只能看到1個在線(他自己),第二個看到兩個(在線)。這是一個奇怪的例子,當becouse我與在線成員的NUMER只發送一個整數,這兩個客戶端看到「2」 - 所以它是正確的,當我嘗試發送到客戶端之前打印網上客戶號(map.size())我看到「2」。所以發送之前是好的,但閱讀後只有「1」(對於第一個客戶端)。這怎麼可能?數據丟失 - 客戶機/服務器

服務器端:

private void rewrite() { 
    online.clear(); 
    for(int key : handlerMap.keySet()) { 
     online.put(handlerMap.get(key).getId(), handlerMap.get(key).getNickname());    
    }  
} 

public void run() { 
    try { 
     ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream()); 
     container = new MsgContainer(); 
     list = new OnlineList(); 

     while(!interrupt) { 
      rewrite(); 
      list.setOnlineList(online); 
      container.setMessage(message); 
      container.setList(list); 
      System.out.println("klucz - "+id+" ----------" 

+container.getList().getOnlineList().size()); //id is an unique id. It shows 2 online `for` 
//1st client and 2 for 2cnd. All ok. But when I send and read on first client's side it `//shows only 1,` 
      oos.writeObject(container); 
      message = null; 
      Thread.sleep(100); 
     } 
     oos.close(); 
    } 
    catch(InterruptedException e) { System.out.println(e); } 
    catch(IOException e) { System.out.println(e); } 

    threadOnlineList.interrupt(); 
} 

客戶端:

public void run() { 
    try { 
     ObjectInputStream ois = new ObjectInputStream(socket.getInputStream()); 
     while(!interrupt) { 
      if(ois.readObject() != null) { 
       MsgContainer container = (MsgContainer) ois.readObject(); 
       //updateList(container.getList().getOnlineList()); 
       System.out.println(container.getList().getOnlineList().size()); 
////shows 
//1 for first client and 2 for second one. 
      } 
      Thread.sleep(100); 
     } 
     ois.close(); 
    } 
    catch(IOException e) { System.out.println(e); } 
    catch(InterruptedException e) { System.out.println(e); } 
    catch(ClassNotFoundException e) { System.out.println(e); } 
} 

回答

1

當第一個客戶端連接,您發送的客戶名單。這包括客戶端1.當客戶端2連接時,您發送客戶端列表。這包括客戶端1和客戶端2.第一個客戶端只看到1個連接,因爲只有一個連接。如果您希望第一個客戶端看到兩個連接,則每次客戶端連接或斷開與服務器的連接時,都需要更新所有客戶端。

+0

是的,我做到這一點。我有一個對象「ConnectionHandler」的地圖的引用。每個新客戶都有自己的「ConnectionHandler」。然後我把這個處理程序放到一個Connection Handlers 的映射中,其中int是一個唯一的ID。當有人連接到服務器時,我將一個新的處理程序放入一個地圖中,並且每個ConnectionHandler對象都引用此地圖,並看到有人已連接(由於此引用了地圖)。 – Sheppard25

+0

現在我明白你來自哪裏。將地圖發送到每個客戶端時,它不會與服務器版本保持同步。它會拍攝服務器版本的快照併發送它的副本。 – supersam654

+0

是的,這可能是真的。你能告訴我如何解決它而不破壞我的整個程序?我非常努力地工作,這可能是沒有用的...... – Sheppard25