2013-01-22 74 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