I need help finishing up a chat program. It's a multithreaded chat that allows for someone at a server and a client to chat back and forth. Both have 2 threads, one reads in from the other person and displays it on screen, the other thread reads the user's keyboard input and send the message to the other. The problem I have ran into, when you type in the exit command, it only closes the write thread of the sender and the read thread of the receiver, the other 2 threads stay active. I don't know how to to get those threads to close too, so the chat ends. Please help.

Here's the code

Client

Code:
import java.io.*; 
import java.net.*;
public class Client {
	public static void main(String[] args) throws UnknownHostException, IOException, InterruptedException {
		Socket cSock = new Socket("localhost", 51220);//client socket command to set which server to contact
		ReadIn rdIn = new ReadIn(cSock);
		WriteOut wtOut = new WriteOut(cSock);
		rdIn.start();
		wtOut.start();			
		do {
			if (rdIn.clSock.isClosed() == true) {
				rdIn.join();
				wtOut.join();
				cSock.close();
			}
			else if (wtOut.clSock.isClosed() == true) {
				rdIn.join();
				wtOut.join();
				cSock.close();
			}
		}
		while(cSock.isConnected() == true);		
	}
}

ReadIn

Code:
import java.io.*;
import java.net.Socket; 
public class ReadIn extends Thread {
	public Socket clSock;
	private BufferedReader inServer;
	public Boolean chat;
	public ReadIn(Socket clSock) {
		this.clSock = clSock;
	}
	public Boolean getChat() {
		return chat;
	}
	public void run() {	
		chat = true;
		String fServ = " ";//message from server
		WriteOut wO = new WriteOut(clSock);
		try {
			inServer = new BufferedReader(new InputStreamReader(clSock.getInputStream()));
		} catch (IOException e1) {
			e1.printStackTrace();
		}
		do {
			if ((clSock.isConnected()) && (wO.clSock.isConnected())) {
			try { 
				fServ = inServer.readLine();
			} catch (IOException e) {
				e.printStackTrace();	
			}			
			if ((fServ != null) && (fServ.contains("EXITEXIT"))) {
				System.out.println("Server: "+fServ);
				chat = false;
				try {
					clSock.close();
					wO.clSock.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				System.out.println("ReadIn");
			}
			else
			{
				System.out.println("Server: "+fServ);
			}
			}
			else if (wO.clSock.isClosed() == true) {
				chat = false;
			}
		}
		while(chat.equals(true));
	}
}

WriteOut

Code:
import java.io.*; 
import java.net.*;
public class WriteOut extends Thread{
	public Socket clSock;
	private DataOutputStream outServer;
	public Boolean chat;
	public WriteOut(Socket clSock) {
		this.clSock = clSock;
	}
	
	public Socket getSock() {
		return clSock;
	}
	public void setSock(Socket clSock) {
		this.clSock = clSock;
	}
	public Boolean getChat() {
		return chat;
	}
	public void run(){
		chat = true;
		BufferedReader fUser = new BufferedReader(new InputStreamReader(System.in));
		String tServ = " ";
		ReadIn rI = new ReadIn(clSock);
		try {
			outServer = new DataOutputStream(clSock.getOutputStream());
		} catch (IOException e1) {
			e1.printStackTrace();
		}//send to server
		do {
			if ((clSock.isConnected()) && (rI.clSock.isConnected())) {
		try {
			tServ = fUser.readLine();
		} catch (IOException e) {
			e.printStackTrace();
			break;
		}
			if (tServ.contains("EXITEXIT")){
				try {
					outServer.writeBytes(tServ + "\n");
				} catch (IOException e) {
					e.printStackTrace();
				} //receive from server
				chat = false;
				System.out.println("WriteOut");
			}
			else if (rI.clSock.isClosed()) {
				chat = false;
			}
			else {
				try {
					outServer.writeBytes(tServ + "\n");
				} catch (IOException e) {
					e.printStackTrace();
				} //receive from server
			}
			}

		}
		while (chat.equals(true));
		try {
			clSock.close();
			rI.clSock.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
Server

Code:
import java.net.*;
public class Server {
	public static void main(String[] args) throws Exception {
		ServerSocket welSock = new ServerSocket(51220);
		Socket conSock = welSock.accept();
		SerRead sRead = new SerRead(conSock, welSock);
		SerWrite sWrite = new SerWrite(conSock);
		sRead.start();		
		sWrite.start();		
		do {

			if(sRead.cSock.isClosed() == true) {
				sRead.join();
				sWrite.join();
				conSock.close();
				welSock.close();
			}
			else if (sWrite.clSock.isClosed() == true) {
				sRead.join();
				sWrite.join();
				conSock.close();
				welSock.close();
			}
		}
		while(conSock.isConnected() == true);
	}	
}

SerRead
Code:
import java.io.*;
import java.net.*;
public class SerRead extends Thread {
	public Socket cSock;
	public ServerSocket wSock;
	private BufferedReader fClient;
	public Boolean chat;
 public SerRead(Socket cSock, ServerSocket wSock) {
	 this.cSock = cSock;
	 this.wSock = wSock;
	}
public void run (){
	 chat = true;
	 String fromClient = " ";//message received from client
	 SerWrite sW = new SerWrite(cSock);
	try {
		fClient = new BufferedReader(new InputStreamReader(cSock.getInputStream()));
	} catch (IOException e1) {
		e1.printStackTrace();
	} 
	 do {
		 if ((cSock.isConnected()) && (sW.clSock.isConnected())) {
		 try {
			fromClient = fClient.readLine();
		} catch (IOException e) {
			e.printStackTrace();
			break;
		}
		 if((fromClient != null)&&(fromClient.contains("EXITEXIT")))
		 {
			 System.out.println("Client: " + fromClient); 
			 chat = false;
			 System.out.println("SerRead");
		 }
		 else {
			 System.out.println("Client: " + fromClient);
		 }
		 }
		 else if (sW.clSock.isClosed() == true) {
			 chat = false;
		 }
	 }
	 while(chat.equals(true));
		try {
			cSock.close();
			wSock.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
 }
}
SerWrite
Code:
import java.io.*;
import java.net.*;
public class SerWrite extends Thread {
	public Socket clSock;
	private DataOutputStream outClient;
	public Boolean chat;
	public SerWrite(Socket clSock) {
		this.clSock = clSock;
	}
	
	public Socket getcSock() {
		return clSock;
	}

	public void setcSock(Socket clSock) {
		this.clSock = clSock;
	}

	public void run(){
	chat = true;
	BufferedReader tClient = new BufferedReader(new InputStreamReader(System.in));
	String toClient = " ";//reply to client
	SerRead sR = new SerRead(clSock, null);
	try {
		outClient = new DataOutputStream(clSock.getOutputStream());
	} catch (IOException e) {
		e.printStackTrace();
	}
	do {
		if ((clSock.isConnected()) && (sR.cSock.isConnected())) {
	try {
		toClient = tClient.readLine();
	} catch (IOException e) {
		e.printStackTrace();
	}
		if(toClient.contains("EXITEXIT")) {
				try {
					outClient.writeBytes(toClient +"\n");
				} catch (IOException e) {
					e.printStackTrace();
				}
				chat = false;
				System.out.println("SerWrite");
			}
		else if (sR.cSock.isClosed()) {
			chat = false;
		}
		else {
			try {
				outClient.writeBytes(toClient +"\n");
			} catch (IOException e) {
				e.printStackTrace();
			}
			}
		}
		}
	while(chat.equals(true));
	try {
		clSock.close();
	} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
}
}