Hi, I am trying to implement a group chat in Java. The chat is fully functional, (the basics). My intention is to capture when a user disconnects to be able to delete their name from the arrayList of the users of the server, but I can not identify when it is disconnected. I have placed a try / catch on my server to capture the SocketException , but it never enters there.
My code for my server is as follows:
import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.ArrayList;
public class ServerChat {
static ArrayList<String> usuarios = new ArrayList<String>();
static ArrayList<PrintWriter> printWriters = new ArrayList<PrintWriter>();
public ServerChat() {
usuarios = null;
printWriters = null;
}
public static void main(String[] args) throws SocketException {
try {
System.out.println("Esperando por peticiones de clientes... ");
ServerSocket ss = new ServerSocket(9001);
while (true) {
try {
Socket soc = ss.accept(); // representa al cliente
System.out.println("Cliente conectado. ");
ManejadorConver manejador = new ManejadorConver(soc, usuarios.size());
manejador.start();
} catch (SocketException e) {
System.out.println("Se ha desconectado un cliente");
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Client Code:
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class ClienteChat {
static JFrame ventanaChat = new JFrame("Aplicación Chat CS");
static JTextArea areaChat = new JTextArea(22, 40); // (filas, columnas)
static JTextField campoTexto = new JTextField(40);
static JLabel espacioBlanco = new JLabel(" ");
static JButton botonEnvio = new JButton("Enviar");
static JLabel nombreSesion = new JLabel(" ");
static BufferedReader entrada;
static PrintWriter salida;
public ClienteChat() {
ventanaChat.setLayout(new FlowLayout());
ventanaChat.add(nombreSesion);
ventanaChat.add(new JScrollPane(areaChat));
ventanaChat.add(espacioBlanco);
ventanaChat.add(campoTexto);
ventanaChat.add(botonEnvio);
ventanaChat.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ventanaChat.setSize(475, 500);
ventanaChat.setVisible(true);
campoTexto.setEditable(false);
areaChat.setEditable(false);
botonEnvio.addActionListener(new Listener());
campoTexto.addActionListener(new Listener());
}
public void encenderCliente() throws Exception {
String dirIP = JOptionPane.showInputDialog(ventanaChat, "Introduce dirección IP:", "Direcci�n IP requerida",
JOptionPane.PLAIN_MESSAGE);
Socket socket = new Socket(dirIP, 9001);
entrada = new BufferedReader(new InputStreamReader(socket.getInputStream()));
salida = new PrintWriter(socket.getOutputStream(), true);
while (true) {
String str = entrada.readLine();
String nombre = null;
if (str.equals("NOMBRENECESARIO")) {
nombre = JOptionPane.showInputDialog(ventanaChat, "Introduce un nickname único:",
"Nickname requerido", JOptionPane.PLAIN_MESSAGE);
salida.println(nombre);
} else if (str.equals("NOMBREPREEXISTENTE")) {
nombre = JOptionPane.showInputDialog(ventanaChat, "Introduce otro nickname:", "Este nickname ya existe",
JOptionPane.WARNING_MESSAGE);
salida.println(nombre);
} else if (str.startsWith("NOMBREACEPTADO")) {
campoTexto.setEditable(true);
nombreSesion.setText("Has hecho login con el nombre: " + str.substring(14));
} else {
areaChat.append(str + "\n");
}
}
}
class Listener implements ActionListener {
public void actionPerformed(ActionEvent e) {
String texto = ClienteChat.campoTexto.getText();
ClienteChat.salida.println(texto);
ClienteChat.campoTexto.setText("");
}
}
public static void main(String[] args) throws Exception {
ClienteChat cliente = new ClienteChat();
cliente.encenderCliente();
}
}
Handler Code:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
public class ManejadorConver extends Thread {
Socket socket;
BufferedReader entrada;
PrintWriter salida;
String nombre;
public ManejadorConver(Socket socket) throws IOException {
this.socket = socket;
}
public void run() {
try {
int i = 0;
entrada = new BufferedReader(new InputStreamReader(socket.getInputStream()));
salida = new PrintWriter(socket.getOutputStream(), true);
while (true) {
if (i > 0) {
salida.println("NOMBREPREEXISTENTE");
} else {
salida.println("NOMBRENECESARIO");
}
nombre = entrada.readLine();
if (nombre == null) {
return;
}
if (!ServerChat.usuarios.contains(nombre)) {
ServerChat.usuarios.add(nombre);
break;
}
i++;
}
salida.println("NOMBREACEPTADO" + nombre);
ServerChat.printWriters.add(salida);
while (true) {
String mensaje = entrada.readLine();
if (mensaje == null) {
return;
}
for (PrintWriter writer : ServerChat.printWriters) {
writer.println(nombre + ": " + mensaje);
}
}
} catch (Exception e) {
System.out.println(e);
}
}
}
PROBLEM : it never enters that try-catch and I can not catch the disconnection.
The console shows me this when I close a client's window:
Waiting for customer requests ... Client connected. java.net.SocketException: Connection reset.
... but it does not enter that try catch
that I put on the server to capture just that Exception
.
Could someone help me out? Thank you very much.