Bueno, el tema es que estoy realizando un trabajo de una aplicación cliente/servidor multihilo donde se espera que el servidor que programo acepte accesos concurrentes.
Trata de una especie de banco con sus cuentas, donde tengo sincronizados los métodos para actualizar esas cuentas.
El problema me surge cuando lanzo más de una instancia del cliente simultáneamente, ya que la última instancia me funciona, pero las anteriores se bloquean. Por consola el servidor me indica : error java.net.Socket socket closed.
He probado de todo pero no doy con la solución. Os adjunto el código por si alguien puede hacer algo. Muchas gracias de antemano.
Servidor.java
Código:
import java.io.*;
import java.net.*;
class Servidor extends Thread {
private int estado;
Socket skCliente;
static final int Puerto = 8888;
private int NumCuenta;
private double Cantidad;
public static DataInputStream flujo_entrada;
public static DataOutputStream flujo_salida;
String menu = "Seleccionar una opción: \n"
+ "[1] Ingresar una cantidad \n"
+ "[2] Reintegrar una cantidad \n"
+ "[3] Consultar el saldo \n"
+ "[0] Salir \n"
+ "Escriba su elección :";
//Esta constante nos va a permitir indicar al cliente cuándo debe escribir
final String control = "escribir";
public static RecursoServidor recursoServidor;
public Servidor(Socket sCliente) {
skCliente = sCliente;
}
public static void main(String[] arg) {
recursoServidor = new RecursoServidor();
try {
// Inicio el servidor en el puerto
ServerSocket skServidor = new ServerSocket(Puerto);
System.out.println("Escucho el puerto " + Puerto);
while (true) {
// Se conecta un cliente
Socket skCliente2 = skServidor.accept();
System.out.println("Cliente conectado");
// Atiendo al cliente mediante un thread
new Servidor(skCliente2).start();
}
} catch (Exception e) {
System.out.println("Error al conectar un cliente"+e.getStackTrace());
}
}
@Override
public void run() {
try {
// Creo los flujos de entrada y salida
flujo_entrada = new DataInputStream(
new BufferedInputStream(skCliente.getInputStream()));
flujo_salida = new DataOutputStream(
new BufferedOutputStream(skCliente.getOutputStream()));
// ATENDER PETICIÓN DEL CLIENTE
flujo_salida.writeUTF("Se ha conectado el cliente de manera correcta");
flujo_salida.flush();
estado = 0;
String comando="";
flujo_salida.writeUTF("Menú de acceso a la Cuenta "
+ "Bancaria \n"
+ "Introduzca Número de Cuenta [0-9]:");
flujo_salida.flush();
flujo_salida.writeUTF(control);
flujo_salida.flush();
NumCuenta =Integer.parseInt(flujo_entrada.readUTF());
do {
switch (estado) {
case 0:
flujo_salida.writeUTF(menu);
flujo_salida.flush();
flujo_salida.writeUTF(control);
flujo_salida.flush();
comando = flujo_entrada.readUTF();
if (comando.equals("1")) {
//Vamos al estado 1, realizar un ingreso
estado = 1;
break;
} else if (comando.equals("2")) {
// Vamos al estado 2, realizar un reintegro
estado = 2;
break;
} else if(comando.equals("3")){
//Vamos al estado 3, consultar el saldo
estado = 3;
break;
}else if(comando.equals("0")){
//Vamos al estado 4, salir
estado=4;
break;
}
break;
case 1:
flujo_salida.writeUTF("Realización de un Ingreso ");
flujo_salida.writeUTF("Cantidad que desea ingresar: ");
flujo_salida.flush();
flujo_salida.writeUTF(control);
flujo_salida.flush();
Cantidad = Double.valueOf(flujo_entrada.readUTF());
new IngresaCuenta(NumCuenta,Cantidad,recursoServidor).start();
//Volvemos al estado 0, el inicio
estado=0;
break;
case 2:
flujo_salida.writeUTF("Realización de un Reintegro ");
flujo_salida.writeUTF("Cantidad que desea reintegrar: ");
flujo_salida.flush();
flujo_salida.writeUTF(control);
flujo_salida.flush();
Cantidad = Double.valueOf(flujo_entrada.readUTF());
new ReintegraCuenta(NumCuenta,Cantidad,recursoServidor).start();
//Volvemos al estado 0, el inicio
estado=0;
break;
case 3:
flujo_salida.writeUTF("Consulta de Saldo \n");
flujo_salida.flush();
//Consultamos la cantidad al número de cuenta correspondiente
Cantidad = recursoServidor.consultarSaldo(NumCuenta);
flujo_salida.writeUTF("Recibiendo: El saldo de la cuenta"
+ " es : "+String.valueOf(Cantidad));
flujo_salida.flush();
//Volvemos al estado 0, el inicio
estado=0;
break;
}
if (comando.equals("0")) {
estado = 4;
}
} while (estado != 4);
// Se cierra la conexión
flujo_salida.writeUTF("Cliente desconectado");
flujo_salida.flush();
skCliente.close();
System.out.println("Cliente desconectado \n");
} catch (Exception e) {
System.out.println("Error :"+e.toString());
}
}
}
Cliente.java
Código:
import java.io.*;
import java.net.*;
import java.util.Scanner;
class Cliente {
static final String HOST = "localhost";
static final int Puerto = 8888;
//Esta constante nos va a permitir indicar al cliente cuándo debe escribir
final String control="escribir";
public Cliente() {
try {
Socket sCliente = new Socket(HOST, Puerto);
// Creo los flujos de entrada y salida
DataInputStream flujo_entrada = new DataInputStream(
new BufferedInputStream(sCliente.getInputStream()));
DataOutputStream flujo_salida = new DataOutputStream(
new BufferedOutputStream(sCliente.getOutputStream()));
String datosEntrada="", datosSalida="";
//Se crea el objeto scanner que leera la entrada del sistema
Scanner sc = new Scanner(System.in);
//Ejecutaremos este bucle hasta que el servidor nos indique que
//estamos desconectados
do {
// procesar mensajes enviados del servidor
datosEntrada = flujo_entrada.readUTF();
//Si no es el mensaje de control, se mostrará por consola
if(!datosEntrada.equals(control)){
System.out.println(datosEntrada);
}
//Si recibimos el mensaje de control, el usuario debe escribir
if(datosEntrada.equals(control)){
datosSalida=sc.nextLine();
flujo_salida.writeUTF(datosSalida);
flujo_salida.flush();
}
} while ( !datosEntrada.equals( "Cliente desconectado" ) );
sCliente.close();
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
public static void main(String[] arg) {
new Cliente();
}
}