Asking for theory about networking chat and games

Hello. I am trying to implement a server and a client for chat between clients and some games like chess or backgammon.

This is my server class. I need help in theory about how i can enriching it with chess support ( for start ).


public class Server implements Runnable{
	private int clientCount = 0;
	private Thread thread;
	private ServerSocket server;
	private ServerThread clients[];
	private Database db;
	
	private GameServerGUI gui;
	
	public Server(){
		db = new Database();
		gui = new GameServerGUI();
		clients = new ServerThread[500];
		try{
			server = new ServerSocket(6969);
			start();
			
		}catch(Exception ex){
			
		}
	}
	
	@Override
	public void run() {
		
		gui.setDisplayArea("Server Started\n");
		gui.setDisplayArea("Waiting for clients ....... \n");
		while(thread != null){
			
			try {
				addThread(server.accept());
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	public void start(){  
    	if (thread == null){  
    		thread = new Thread(this); 
    		thread.start();
    	}
    }
    
    @SuppressWarnings("deprecation")
    public void stop(){  
    	if (thread != null){  
    		thread.stop(); 
    		thread = null;
    	}
    }
    
    private int findClient(int ID){  
    	for (int i = 0; i < clientCount; i++){
    		if (clients[i].getID() == ID){
    			return i;
    		}
    	}
    	
    	return -1;
    }
	
    public synchronized void handle(int ID, Message msg) throws SQLException{
    	if (msg.content.equals(".bye")||msg.content.equals("signout")){
    		Announce("signout", "SERVER", msg.sender);
    		remove(ID); 
    		//SendUserList(msg.sender);
    	}else{
    		if(msg.type.equals("login")){
    			
    			String username = msg.sender.toString();
    			String password = msg.content.toString();
    			
    			if(db.userAuthenticator(username, password)==true){
    				clients[findClient(ID)].username = msg.sender;
        			clients[findClient(ID)].send(new Message("login", "SERVER", "TRUE", msg.sender));
        			Announce("newuser", "SERVER", msg.sender);
                    SendUserList(msg.sender);
    			}else{
    				clients[findClient(ID)].send(new Message("login", "SERVER", "FALSE", msg.sender));
    			}
    		}else if(msg.type.equals("signup")){
    			System.out.println("User "+msg.sender+" connected. Password "+msg.content);
    			System.out.println("Yeah !!!");
    		}else if(msg.type.equals("message")){
    			gui.setDisplayArea("Message "+ msg.content+ " from "+ msg.sender+" for "+msg.recipient+"\n");
    			findUserThread(msg.recipient).send(new Message(msg.type, msg.sender, msg.content, msg.recipient));
    		}
    	}
    }
    
    public void Announce(String type, String sender, String content){
    	Message msg = new Message(type, sender, content, "All");
    	for(int i = 0; i < clientCount; i++){
    		clients[i].send(msg);
    	}
    }
    
    public void SendUserList(String toWhom){
    	for(int i = 0; i < clientCount; i++){
    		findUserThread(toWhom).send(new Message("newuser", "SERVER", clients[i].username, toWhom));
    	}
    }
    
    public ServerThread findUserThread(String usr){
    	for(int i = 0; i < clientCount; i++){
    		if(clients[i].username.equals(usr)){
    			return clients[i];
    		}
    	}
    	
    	return null;
    }
    
    @SuppressWarnings("deprecation")
    public synchronized void remove(int ID){  
    	int pos = findClient(ID);
    	if (pos >= 0){  
    		ServerThread toTerminate = clients[pos];
    		gui.setDisplayArea("Removing client thread " + ID + " at " + pos+"\n");
    		gui.setDisplayArea("---"+"\n");
    		//System.out.println("\nRemoving client thread " + ID + " at " + pos);
    		if (pos < clientCount-1){
    			for (int i = pos+1; i < clientCount; i++){
    				clients[i-1] = clients[i];
    			}
    		}
    		clientCount--;
    		try{  
    			toTerminate.close(); 
    		}catch(IOException ioe){  
    			System.out.println("\nError closing thread: " + ioe); 
    		}
    		toTerminate.stop(); 
    	}
    }
    
	private void addThread(Socket socket){
		if(clientCount<clients.length){
			gui.setDisplayArea("Client connected "+ socket+"\n");
			clients[clientCount] = new ServerThread(this, socket);
			try{
				clients[clientCount].open();
				clients[clientCount].start();
				clientCount++;
			}catch(Exception ex){
				gui.setDisplayArea("Error opening thread:" + ex+"\n");
			}
		}else{
			gui.setDisplayArea("Max users\n");
		}
	}
	private class ServerThread extends Thread{
		public Server server;
		public Socket socket;
		public int ID;
		public String username;
		public ObjectInputStream streamIn  =  null;
	    public ObjectOutputStream streamOut = null;
	    
		public ServerThread(Server server, Socket socket){
			super();
			this.server = server;
			this.socket = socket;
			ID = socket.getPort();
		}
		
		public void send(Message msg){
	    	try {
	    		streamOut.writeObject(msg);
	    		streamOut.flush();
	    	}catch (IOException ex) {
	    		System.out.println("Exception [SocketClient : send(...)]");
	    	}
	    }
	    
	    public int getID(){  
	    	return ID;
	    }
	    
	    public void run(){
	    	gui.setDisplayArea("Server thread "+ID+" running.\n");
	    	while(true){
	    		try{
	    			Message msg = (Message) streamIn.readObject();
	    			server.handle(ID, msg);
	    		}catch(Exception ex){
	    			gui.setDisplayArea(ID + " ERROR reading: " + ex.getMessage()+"\n");
	    			server.remove(ID);
	    			stop();
	    		}
	    	}
	    }
	    
	    public void open() throws IOException {  
	    	streamOut = new ObjectOutputStream(socket.getOutputStream());
	    	streamOut.flush();
	    	streamIn = new ObjectInputStream(socket.getInputStream());
	    }
	    
	    public void close() throws IOException {  
	    	if (socket != null)    socket.close();
	    	if (streamIn != null)  streamIn.close();
	    	if (streamOut != null) streamOut.close();
	    }
	}
}

As a first step you need to define a protocol, i.e. the way a client will send moves to the server and how the servers answers to such data sent by the client.

Also, you should find another solution but thread.stop() There are cleaner ways to terminate threads.

The way to do this is calling .join(); on a thread.

The trick is you can’t call .join() in a run() method of the current thread (if the object is Runnable), you have to call it from outside of the thread. So in your Server run method you instead of while(thread != null) use a boolean “running” and just set to false to break the loop (this object’s thread will die when it reaches the end of the run() method, you should use a .join() in the object that instantiates the Server object, or in main).

When you reach the end of run() for each client that still has a thread make sure to tell them to stop looping (boolean) and then do a .join() on those threads (or do it for an individual client when they disconnect)

I have a class called Message


public class Message implements Serializable{
    
    private static final long serialVersionUID = 1L;
    public String type, sender, content, recipient;
    
    public Message(String type, String sender, String content, String recipient){
        this.type = type; 
        this.sender = sender; 
        this.content = content; 
        this.recipient = recipient;
    }
    
    @Override
    public String toString(){
        return "{type='"+type+"', sender='"+sender+"', content='"+content+"', recipient='"+recipient+"'}";
    }
}