Problemas con etiquetas y sockets

Hola de nuevo.
Una duda tonta, pero que me tiene desconcertado.
Intento cambiar el valor de un JLabel con setText y no me lo cambia.
Échale un vistazo al código a ver qué ves mal.
...
Mensaje.setForeground(Color.blue);
Mensaje.setText("Comprobando identidad..."); <-- ESTO NO ME LO HACE
new Cliente(getVisibilidadControlable());
......
class Cliente extends JFrame implements General{
BufferedReader is=null; // Canal de entrada para la lectura de datos por el socket
PrintWriter os=null; // Canal de salida para el envio de datos por el socket
Socket s=null; // Socket para la comunicación con el servidor
Integer limite=0;
String devuelto="";
VisibilidadControlable Top;
Integer error=0;
public Cliente(final VisibilidadControlable Top) {
this.Top=Top;
DataInputStream stdin=new DataInputStream(System.in); // Canal para la lectura de la entrada estándar
String sendString = "";
int longCad;
char Separador=(char)13;
try{ s=new Socket("172.17.9.251",1315); // realizamos una conexión en la misma máquina con
// el servidor que esté conectado al puerto 3355
s.setSoTimeout(1000);
is=new BufferedReader(
new InputStreamReader(
s.getInputStream())); // Obtenemos un canal de entrada (lectura) del socket
// Aplicamos estratos para poder leer tipos primitivos
// y utilizamos un buffer para la lectura
os=new PrintWriter(
new BufferedWriter(
new OutputStreamWriter(
s.getOutputStream())),true);
// Obtenemos un canal de salida (escritura) del socket
// Utilizamos un buffer para la lectura y escribiremos
// texto
} // Capturamos las excepciones que puede lanzar el código
catch(UnknownHostException e){ System.out.println("El host no existe\n"); error=1; }
catch(IOException e){ System.out.println("Error de E/S en la conexión\n"); error=1; this.Top.modificaEstado('s');}
if (error==0 && s!=null && is!=null && os!=null){
try{
// sendString="On" + Separador + "med104" + Separador + "1234" + Separador + cifrando("123ñ456") + Separador;
sendString="On" + Separador + this.Top.getEquipo() + Separador + this.Top.getDNI() + Separador + cifrando(this.Top.getPwd()) + Separador;
os.println(sendString); //Enviamos el mensaje al servidor
System.out.print("Login: " + this.Top.getEquipo() + this.Top.getDNI() + this.Top.getPwd() + "\n");
System.out.print("Cadena enviada: " + sendString + "\n");
System.out.println("Recibo: " + is.readLine());
System.out.println("Recibo: " + is.readLine());
System.out.println("Recibo: " + is.readLine());
System.out.println("Recibo: " + is.readLine());
// new Thread ( new Tiempo(referencia()) , "").start();
new Tiempo(referencia());
System.out.println("Devuelto desde Cliente:" + devuelto + "\n");
System.out.println("Limite desde Cliente:" + String.valueOf(limite) + "\n");
this.Top.modificaDevuelto(getDevuelto());
this.Top.modificaLimite(getLimite());
} // recibimos la respuesta
catch (IOException e){ System.out.println("Error de E/S en la conexión\n"); }
System.out.println("El cliente acaba\n");
}
}
...
¿Cómo se puede controlar el time out del socket?. Es que si no encuentra la IP se queda un ratazo
esperando. Le he puesto la instrucción "s.setSoTimeout(1000);" pero no me hace nada.
Creo que no actualiza la etiqueta porque se queda pillado con el socket.
Lo he probado incluso modificando la etiqueta con un hilo, para que sea independiente de la
ejecución de "Cliente" pero no responde. Incluso intentando modificar la etiqueta desde dentro
de "Cliente" antes de crear el socket.
¿Alguna idea?.
1

1 Respuesta

109.425 pts. Mas de 15 años de experiencia en Java, Javascript y HTML
Puede ser que no te refresque el contenido del texto por lo del socket. Si comentas (temporalmente, para hacer una prueba) la línea de creación de la clase Cliente, ¿te cambia el texto? Si lo cambia, es que efectivamente, es el socket lo que está bloqueando el repintado de la pantalla. Si no lo cambia, habrá que biscar el problema en otro lado, más concretamente en la clase Top.
Ahora vamos con lo del timeout del socket. Varios consejos:
1) Implementa la interfaz Runnable en la clase Cliente. Create un método run() y mete dentro el código donde haces la conexión del socket, en vez de hacerlo en el constructor. En el constructor tendrás que tener algo como esto:
Thread t = new Thread(this);
t.start();
Esto disparará tu método run() en un hilo aparte, y no te bloqueará el resto de la aplicación.
2) Pon trazas del tipo System. Out. Println() para ver dónde se te queda colgado el socket. Si se queda en la conexión inicial, no sirve de nada el setSoTimeout() porque todavía no se ha ejecutado esa línea. Pero no lo quites, porque cuando conecte bien, te será útil.
3) Si se te queda colgado en la conexión inicial, prueba a hacer la conexión de este modo:

SocketAddress sockaddr = new InetSocketAddress(addr, port);
s = new Socket();
try{
   s.connect( sockaddr  , 10000); //10 segundos de timeout

}catch (IOException ioex){
//tu codigo

}
catch (SocketTimeoutException stoex){
//tu codigo

}
catch (IllegalBlockingException ibex){
//tu codigo

}
catch(IllegalArgumentException iaex){
//tu codigo

}
De este modo controlas el tiempo de conexión.
He optado por el control de tiempo de conexión, más que por el hilo de "Cliente", porque hacer esto último me lleva cambiar muchas cosas del código.
Con el control de tiempo de conexión, va estupendo y ya no necesito colocar el mensaje mientras hace la conexión, pues si no se conecta en 1 seg es que algo va mal.
Muchas gracias por tu solución.
Saludos.

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas