问题
I am using the following code to connect with java socket from an Applet client. I store Client's IP Address and some random number in every NEW connection happening in addNewClient() function in the below code. I store this info in HashMap. I add more client info in the ArrayList of this HashMap.
If there is already some client info in ArrayList, I need to read through it. I am trying that in SocketConnection class below using Iterator.
The problem I see is, I am adding some 3 client info into the ArrayList. But, when i read through it using Iterator, it can get only last added Client info, and other KEYS are just getting empty. But, at the same time, its giving the ArrayList size correctly as 3
Could some experts please refer my below complete code, and advise me what could be the problem in there?
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;
}
}
UPDATE: As per Amrish suggestion, changed the following code, it solved the issue.
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:
Your Arraylist has 3 hashmap but each hashmap has only one object. Hence , you are getting size as 3 but only one object is returned when you iterate over the hashmap.
回答2:
Problem here is you are comparing two different things:
int totalClientList = clientList.size();
this will give you the number of clients you have in your list:
HashMap<String, ClientInfo> tmpData = (HashMap<String, ClientInfo>) clientList.get(i);
Set<String> key = tmpData.keySet();
This will give you the keys of the i'th client. which is different than the total clients.
What you should do is to drop List of hashmaps and just use a single HashMap to keep track of all the clients.
Hope this helps.
Change your SocketThread to remove list
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();
}
}
}
change your SockectConnection to remove list
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();
}
}
Change Add New Client:
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);
}
}
I just edited your code, it should give you a start. Hope this helps.
回答3:
You are talking about two different things. One is the size of a list, the other one is the size of a hashMap. Try this:
int mapSize = tmpData.size();
You can get the size of the map and check if it's right.
来源:https://stackoverflow.com/questions/21823938/hashmap-data-not-appending-new-data-into-arraylist