2014-02-17 44 views
0

我正在使用以下代码从Applet客户端与java套接字进行连接。我在下面的代码中将addNewClient()函数中发生的每个NEW连接中存储了客户端的IP地址和一些随机数。我将此信息存储在HashMap中。我在HashMapArrayList中添加更多客户信息。HashMap数据不会将新数据附加到ArrayList中

如果ArrayList已经有客户信息了,我需要仔细阅读。我在SocketConnection课程中使用Iterator来尝试。

我看到的问题是,我将3个客户端信息添加到ArrayList。但是,当我使用Iterator来读取它时,它只能获得最后添加的客户端信息,而其他KEYS只是变空了。但是,在同一时间,它正确地给ArrayList的大小为3

请问有些专家请参考我的下面的完整代码,并告诉我什么可能是在那里的问题?

public class DataSharingSocketListner { 
      public static void main(String[] args) { 

       System.out.println("client trying to connect before thread creation"); 

       Thread thr = new Thread(new SocketThread()); 
       thr.start(); 
      } 
     } 

     class SocketThread implements Runnable { 

      HashMap<String, ClientInfo> clientInfo = new HashMap<String, ClientInfo>(); 

      ArrayList<HashMap<String, ClientInfo>> myList = new ArrayList<HashMap<String, ClientInfo>>(); 

      @Override 
      public void run() { 
       try { 
        System.out.println("client trying to connect after thread creation"); 

        ServerSocket server = new ServerSocket(8080); 
        while (true) { 

         SocketConnection client = new SocketConnection(server.accept(), clientInfo, myList); 
         client.start(); 
        } 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } 

     } 

     class SocketConnection extends Thread { 
      InputStream input; 
      PrintWriter output; 
      Socket socket; 
      ObjectOutputStream out = null; 
      OutputStream clientOutput; 
      Scanner scannerObj; 
      HashMap<String, byte[]> hm; 
      InetAddress addr; 

      HashMap<String, ClientInfo> clientinfo; 

      ArrayList<HashMap<String, ClientInfo>> clientList; 

      public SocketConnection(Socket socket, HashMap<String, ClientInfo> clientInfo, ArrayList<HashMap<String, ClientInfo>> myList) { 

       super("Thread 1"); 

       this.socket = socket; 
       //this.hm = dataHashMap; 
       this.clientinfo = clientInfo; 
       this.clientList = myList; 

       try { 

    // IT IS PRINTING TOTAL SIZE 3 SUCCESSFULLY HERE 
        int totalClientList = clientList.size(); 
        System.out.println("totalClientList: " + totalClientList); 

        if (totalClientList>0) 
        { 
         for (int i=0; i<totalClientList; i++) 
         { 
          System.out.println("client list reading " + i); 

          HashMap<String, ClientInfo> tmpData = (HashMap<String, ClientInfo>) clientList.get(i); 

    // IT IS GETTING ONLY THE LAST KEY, OTHER KEYS ARE SHOWING EMPTY 
          Set<String> key = tmpData.keySet(); 
          Iterator it = key.iterator(); 

          while (it.hasNext()) { 
           System.out.println("hasNexthasNext"); 
           String hmKey = (String)it.next(); 
           ClientInfo hmData = (ClientInfo) tmpData.get(hmKey); 

           System.out.println("Key: "+hmKey +" & Data: "+hmData.getRandomNo()); 
           it.remove(); // avoids a ConcurrentModificationException 
          } 
         } 
         // TO ADD NEW CLIENT EVERY TIME 
         addNewClient(); 
        } 
        else { 
         System.out.println("Client List shows empty"); 

         // TO ADD NEW CLIENT EVERY TIME 
         addNewClient(); 
        } 

        // Not used yet, will be used 
        input = socket.getInputStream(); 
        scannerObj = new Scanner(socket.getInputStream()); 
        clientOutput = socket.getOutputStream(); 


       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } 
      public int genRandomNumber() { 
       Random r = new Random(System.currentTimeMillis()); 
       return 10000 + r.nextInt(20000); 
      } 
      String getLocalIP() { 
       InetAddress inetAddress = null; 
       String ipAddress = null; 
       try { 
        inetAddress = InetAddress.getLocalHost(); 
        ipAddress = inetAddress.getHostAddress(); 
       } catch (UnknownHostException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
       System.out.println("ipAddress : " + ipAddress); 

       return ipAddress; 
      } 
      void addNewClient() { 

       String ipAddress = getLocalIP(); 

       if (ipAddress!=null) 
       { 
        ClientInfo clientobj = new ClientInfo(); 

        clientobj.setIPAdd(ipAddress); 
        int randno = genRandomNumber(); 
        System.out.println("genRandomNumber() : " + randno); 
        clientobj.setRandomNo(randno); 

        String key = String.valueOf(randno); 

        clientinfo.put(key, clientobj); 

        clientList.add(clientinfo); 
       } 
      } 

      @Override 
      public void run() { 

       System.out.println("Going to Read client data"); 

       //do something 
       { 
        String hostIP = addr.getHostAddress() ; 
        System.out.println("hostIP: " + hostIP); 

        //do something 
       } 
      } 



     } 

     class ClientInfo { 

      private String IPAddress; 
      private long RandomNumber; 
      private byte[] data; 

      public static void main(String []args) { 
       System.out.println("Client info Main"); 
      } 

      //Setter 
      void setIPAdd (String ip) { 
       System.out.println("setIPAdd called"); 
       IPAddress = ip; 
      } 
      void setRandomNo (long randomno) { 
       RandomNumber = randomno; 
      } 
      void setImageData (byte[] imgData) { 
       data = imgData; 
      } 

      //Getter 
      String getIPAdd() { 
       return IPAddress; 
      } 
      long getRandomNo() { 
       return RandomNumber; 
      } 
      byte[] getImageData() { 
       return data; 
      } 

     } 

更新:按照Amrish的建议,更改了下面的代码,它解决了这个问题。

int totalClientList = clientList.size(); 
         System.out.println("totalClientList: " + totalClientList); 

         if (totalClientList>0) 
         { 
          for (int i=0; i<totalClientList; i++) 
          { 
           System.out.println("client list reading " + i); 

           HashMap<String, ClientInfo> tmpData = (HashMap<String, ClientInfo>) clientList.get(i); 
           Set<String> key = tmpData.keySet(); 
           System.out.println("key: " + key); 
     } 
          addNewClient(); 
         } 
         else { 
          System.out.println("Client List shows empty"); 
          addNewClient(); 
         } 

    void addNewClient() { 

       String ipAddress = getLocalIP(); 

       if (ipAddress!=null) 
       { 
// CREATE NEW OBJECT EVERY TIME WHEN STORING 
        HashMap<String, ClientInfo> clientInfo = new HashMap<String, ClientInfo>(); 
        ClientInfo clientobj = new ClientInfo(); 

        //System.out.println("Test log 1" + clientobj); 
        clientobj.setIPAdd(ipAddress); 
        // System.out.println("Test log 2"); 
        int randno = genRandomNumber(); 
        System.out.println("genRandomNumber() : " + randno); 
        clientobj.setRandomNo(randno); 

        String key = String.valueOf(randno); 
        //System.out.println("key: " + key); 

        clientInfo.put(key, clientobj); 

        clientList.add(clientInfo); 
       } 
      } 

回答

1

您的Arraylist有3个散列表,但每个散列表只有一个对象。因此,您将size设置为3,但在迭代hashmap时只返回一个对象。

+0

我尝试添加HashMap对象分别为每个时间商店,但也观察到同样的问题。 – Stella

+0

好吧,阿姆里什,你发现问题很完美!每次存储时我都尝试添加新的hasmap对象,现在它会正确列出所有项目。 – Stella

+0

我现在更新了修改的工作代码。 – Stella

0

这里的问题你在比较两个不同的东西:

int totalClientList = clientList.size(); 

这会给你你在你的名单有客户端的数量:

HashMap<String, ClientInfo> tmpData = (HashMap<String, ClientInfo>) clientList.get(i); 
Set<String> key = tmpData.keySet(); 

这会给你的钥匙的i'th client。这是不同于total clients.

你应该做的是drop List of hashmaps,只是使用single HashMap来跟踪所有的客户端。

希望这会有所帮助。

更改您的SocketThread删除列表

class SocketThread implements Runnable { 

    HashMap<String, ClientInfo> clientInfo = new HashMap<String, ClientInfo>(); 


    @Override 
    public void run() { 
     try { 
      System.out.println("client trying to connect after thread creation"); 

      ServerSocket server = new ServerSocket(8080); 
      while (true) { 

       SocketConnection client = new SocketConnection(server.accept(), clientInfo); 
       client.start(); 
      } 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

} 

改变你的SockectConnection删除列表

  HashMap<String, ClientInfo> clientinfo; 

      public SocketConnection(Socket socket, HashMap<String, ClientInfo> clientInfo) { 
       super("Thread 1"); 

       this.socket = socket; 
       //this.hm = dataHashMap; 
       this.clientinfo = clientInfo; 

       try { 

    // IT IS PRINTING TOTAL SIZE 3 SUCCESSFULLY HERE 
        int totalClientList = clientInfo.size(); 
        System.out.println("totalClientList: " + totalClientList); 

        if (totalClientList>0) 
        { 


    // IT IS GETTING ONLY THE LAST KEY, OTHER KEYS ARE SHOWING EMPTY 
          Set<String> key = clientInfo.keySet() 
          Iterator it = key.iterator(); 

          while (it.hasNext()) { 
           System.out.println("hasNexthasNext"); 
           String hmKey = (String)it.next(); 
           ClientInfo hmData = (ClientInfo) tmpData.get(hmKey); 

           System.out.println("Key: "+hmKey +" & Data: "+hmData.getRandomNo()); 
           it.remove(); // avoids a ConcurrentModificationException 
          } 

         // TO ADD NEW CLIENT EVERY TIME 
         addNewClient(); 
        } 
        else { 
         System.out.println("Client List shows empty"); 

         // TO ADD NEW CLIENT EVERY TIME 
         addNewClient(); 
        } 

        // Not used yet, will be used 
        input = socket.getInputStream(); 
        scannerObj = new Scanner(socket.getInputStream()); 
        clientOutput = socket.getOutputStream(); 


       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } 

更改添加新客户:

void addNewClient() { 

     String ipAddress = getLocalIP(); 

     if (ipAddress!=null) 
     { 
      ClientInfo clientobj = new ClientInfo(); 

      clientobj.setIPAdd(ipAddress); 
      int randno = genRandomNumber(); 
      System.out.println("genRandomNumber() : " + randno); 
      clientobj.setRandomNo(randno); 

      String key = String.valueOf(randno); 

      clientinfo.put(key, clientobj); 

     } 
    } 

我刚编辑你的代码,它应该给你一个开始。希望这可以帮助。

+0

能否提供样品请 – Stella

+0

请看更新的回答 – Sanjeev

+0

这样,它只会存储最后添加的数据,它不会添加到数组列表中。 – Stella

0

你在谈论两件不同的事情。一个是列表的大小,另一个是hashMap的大小。 试试这个:

int mapSize = tmpData.size(); 

你可以在地图的大小,并检查它是否是正确的。

+0

我想读取添加到ArrayList中的3个数据。我将3个HasMap对象添加到ArrayList中,当我读它时,它只给了我最后添加的数据,其他人显示为空。 – Stella