Reputation: 333
I have a simple XO game which have multiple clients play XO Chess with each other. I built a sever which communicate with every clients connected. ( When a client connect to server, i create a new class (implement Runnable) handle that socket then start the Thread ... I have a List store all the client in the outer class ) When a client want to start a game , he make himself a new server and send the info of the Room(his name, IP address, port...) to the Server. And in the server I have a List which add a that room to the list and send it to others Clients.
public class ServerController {
private ServerView view;
private ServerSocket myServer;
private int serverPort = 8881;
private List<ExchangeData> list;
private volatile List<Room> rooms;
public ServerController(ServerView view) {
this.view = view;
openServer(serverPort);
view.showMessage("TCP server is running...");
list = new ArrayList<ExchangeData>();
rooms = new ArrayList<Room>();
while (true) {
listening();
}
}
private void openServer(int portNumber) {
....
}
private void listening() {
try {
Socket clientSocket = myServer.accept();
ExchangeData ex = new ExchangeData(clientSocket);
Thread thread = new Thread(ex);
thread.start();
list.add(ex);
} catch (IOException e) {
System.out.print(e.toString());
}
}
class ExchangeData implements Runnable {
private Socket clientSocket;
private ObjectOutputStream oos;
private ObjectInputStream ois;
private boolean run = true;
public ExchangeData(Socket socket) {
try {
clientSocket = socket;
oos = new ObjectOutputStream(clientSocket.getOutputStream());
ois = new ObjectInputStream(clientSocket.getInputStream());
} catch (Exception ex) {
System.out.println(ex.toString());
}
}
public void closeConnection() {
.....
}
public void sendData(Object o) {
try {
oos.writeObject(o);
} catch (Exception ex) {
view.showMessage(ex.toString());
}
}
public void run() {
try {
while (run) {
Object data = ois.readObject();
if (data instanceof Object[]) {
Object[] o = (Object[]) data;
String s = o[0].toString();
if (s.equalsIgnoreCase("Open Room")) {
Room r = (Room) o[1];
String username = r.getUsername();
InetSocketAddress isa = r.getIsa();
**rooms.add(r);**
List<Room> l = new ArrayList<Room>(rooms);
for (ExchangeData ex : list) {
ex.sendData(username + " Open A room at : "
+ isa);
**ex.sendData(rooms);**
}
} else if (s.equalsIgnoreCase("Close Room")) {
Room room = (Room) o[1];
rooms.remove(room);
List<Room> l = new ArrayList<Room>(rooms);
for (ExchangeData ex : list) {
ex.sendData(l);
}
}
} else if (data instanceof String) {
String s = data.toString();
if (s.equalsIgnoreCase("Quit")) {
stopThread();
list.remove(this);
closeConnection();
}
}
}
} catch (Exception ex) {
try {
stopThread();
list.remove(this);
} catch (ExceptionInInitializerError e) {
e.printStackTrace();
}
}
}
}
}
The problem is when i execute rooms.add(r) , others Thread doesn't seem to see that "update". For example: 1) First player opens a Room - the rooms size is 1; 2) Second player opens a new Room - the rooms size is now 2 ( I tried to add some lines of code in side the method sendData(Object o ) which println the size of rooms and all is 2. But when the line ObjectoutputStream.write(o) is executed, it actually write the value of rooms that Thread(first player) hold before which is 1. If i create new list like List l = new ArrayList(rooms) like i did with the "Closing Room" then send this , it work. I don't understand why ? Someone please explain this to me. Sorry for my bad English :(.
Upvotes: 0
Views: 703
Reputation: 692023
When you send the same object several time through a given ObjectOutputStream, the stream writes the full object state the first time, but only sends some reference to this object afterwards.
This allows sending complex graphs of objects with cyclic references without consuming too much bandwidth and without going into infinit loops (send A which references B, so send B which references A, so send A which references B, etc.).
So, if you want to send a fresh copy of your list, you'll have to use the reset()
method of ObjectOutputStream first.
Upvotes: 1