Foro sobre Java SE > servidor clientes trivial
en la clase del hilo tengo el siguiente código:
package trivial;
import java.io.*;
import java.net.*;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
public class hilocliente extends Thread
{
int nPregunta=0;
//nuevo array de preguntas y respuestas:
preguntasRespuestas arrayPregResp[]=new preguntasRespuestas[4];
String mensaje="";
//defino el socket o conexion e inicializo a null
Socket s = null;
//defino los flujos de entrada y de saalida
//BufferedReader f_entrada;
//PrintWriter f_salida;
//entrada
DataInputStream fentrada;
//salida
DataOutputStream fsalida;
//declaracion arraylist de sockets
ArrayList<Socket> arraySockets;
public hilocliente(Socket s, ArrayList arraySockets/*,preguntasRespuestas arrayPregResp[]*/)
{
this.s=s;
this.arraySockets=arraySockets;
try
{
//creo el flujo de entrada del cliente al hilo
//f_entrada = new BufferedReader (new InputStreamReader(s.getInputStream()));
fentrada=new DataInputStream(s.getInputStream());
//creo el flujo de salida del hilo al cliente
//f_salida=new PrintWriter(s.getOutputStream());
fsalida=new DataOutputStream(s.getOutputStream());
}
catch(Exception e)
{
System.out.println("error: "+e.getMessage());
}
}
public void run()
{
System.out.println("nuevo cliente conectado");
llenarArrayPregResp(arrayPregResp);
try
{
fsalida.writeUTF("Bienvendido al juego de respuestas y preguntas en red de Imanol.\nPara cada pregunta usted tendrá 4 posibles respuestas: A,B,C ó D");
fsalida.writeUTF(arrayPregResp[nPregunta].obtenerPregunta()+"\n A-"+arrayPregResp[nPregunta].obtenerR1()+" B-"+arrayPregResp[nPregunta].obtenerR2()+" C-"+arrayPregResp[nPregunta].obtenerR3()+" D-"+arrayPregResp[nPregunta].obtenerR4());
//recibo respuesta del usuario
mensaje=fentrada.readUTF().trim();
//System.out.println("este es el mensaje: "+mensaje);
//recibo mensaje desde cliente
while(mensaje!=null && nPregunta<4)//mensaje=f_entrada.readLine())!=null //(mensaje=fentrada.readUTF())
{
//comprobación respuesta
if(mensaje.compareToIgnoreCase(arrayPregResp[nPregunta].obtenerRespuestaCorrecta())==0)
{
//mando mensaje acierto al cliente
fsalida.writeUTF("1");
}
else//if mensaje!= respuesta_correcta
{
//mando mensaje has fallado al cliente
fsalida.writeUTF("0");
}
nPregunta++;
System.out.println(mensaje+"\n");
if(nPregunta<4)
{
enviarMensaje(mensaje);
System.out.println("esperando a recibir mensaje...\n");
//mensaje="";
fsalida.writeUTF(arrayPregResp[nPregunta].obtenerPregunta()+"\n A-"+arrayPregResp[nPregunta].obtenerR1()+" B-"+arrayPregResp[nPregunta].obtenerR2()+" C-"+arrayPregResp[nPregunta].obtenerR3()+" D-"+arrayPregResp[nPregunta].obtenerR4());
mensaje=fentrada.readUTF().trim();
}
}
}
catch(SocketException e)//-> primero en las excepciones expecificas y despues las genericas por si acaso
{
System.out.println("cliente desconectado");
}
catch(Exception e)
{
System.out.println("error: "+e.getMessage());
}
//cierro los flujos y la conexion del socket:
try
{
System.out.println("fuera de la espera");
//f_entrada.close();
fentrada.close();
//f_salida.close();
fsalida.close();
s.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
public void enviarMensaje(String mensaje)
{
//creo un nuevo flujo para cada socket e imprimo
for(int x=0;x<arraySockets.size();x++)
{
try
{
DataOutputStream fsal=new DataOutputStream(arraySockets.get(x).getOutputStream());
//fsal.writeBytes(mensaje);
fsal.writeUTF(mensaje);
//System.out.println("conexion: "+arraySockets.get(x)+" tamaño del array de conexiones: "+arraySockets.size());
}
catch (IOException e)
{
e.getMessage();
}
}
}
public static void llenarArrayPregResp(preguntasRespuestas arrayPregResp[])
{
//cuatro objetos de almacenaje de preguntas y respuestas:
arrayPregResp[0]=new preguntasRespuestas("¿cuál de los siguientes jugadores de fútbol no jugó en el F.C.Barcelona durante su carrera fubolística?","ronaldo","pelé","figo","maradona","B");
arrayPregResp[1]=new preguntasRespuestas("¿cuántos colores tiene actualmente la bandera de Japón?","4","5","2","ninguno","C");
arrayPregResp[2]=new preguntasRespuestas("presidente actual de los Estados Unidos de América","clinton","reagan","alá","obama","D");
arrayPregResp[3]=new preguntasRespuestas("¿cuál fue el invento más notorio de Alfred Nobel? la...","polea","dinamita","rueda","aspirina","B");
}
}
en la clase cliente el código es el siguiente:
package trivial;
import java.io.*;
import java.net.*;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;
//importo el array dinamico
import static trivial.server.arraySockets;
public class cliente
{
public static void main(String[] args) throws IOException, InterruptedException
{
String mensaje;//, recibido="";
int puntos=0,nResp=0;
String resp="";
//puerto por el que fluyen los datos:
int puerto=5005;
//String ip=JOptionPane.showInputDialog("introduce tu ip: ");
//Socket cliente=new Socket(InetAddress.getByName(ip), puerto);
Socket cliente=new Socket("localhost",puerto);
//creamos flujho de salida - del servidor a el cliente
DataOutputStream fsalida=new DataOutputStream(cliente.getOutputStream());
//creamos flujo de entrada - del cliente al servidor
DataInputStream fentrada=new DataInputStream(cliente.getInputStream());
//entrada estandar(definicion y creacion del flujo) :
BufferedReader f_stadar= new BufferedReader (new InputStreamReader(System.in));
//DataInputStream fstandar=new DataInputStream(new DataInputStream(System.in));
//recibimos el saludo del hilo
System.out.println(fentrada.readUTF());
//recibo pregunta
System.out.println("\n"+fentrada.readUTF());
//pido que se introduzca un mensaje para enviar
System.out.println("introduzca respuesta: ");
//leo por teclado-de consola
mensaje=f_stadar.readLine().toUpperCase().trim();
//System.out.println(mensaje);
while(mensaje!=null && nResp<4)
{
fsalida.writeUTF(mensaje);
resp=fentrada.readUTF().trim();
if(resp.compareTo("1")==0)
{
puntos=puntos+5;
System.out.println("respuesta correcta - puntos: "+puntos);
}
else //si has fallado
{
System.out.println("respuesta incorrecta!");
}
imprimirMensaje(fentrada,fsalida);
nResp++;
/*******************************************************************
* esta parte evitaria la excepción EOFException o end of file,
* esta se produce cuando intentamos leer algo de un flujo cerrado
* o un fichero en el que el puntero apunta al final de los registros
* en nuestro caso se produce al intentar leer mediante la instrucción:
* fentrada.readUTF();
*******************************************************************/
if(nResp<4)
{
//recibo pregunta
System.out.println("\n"+fentrada.readUTF());
System.out.println("introduzca respuesta: ");
//leo respuesta de consola
mensaje=f_stadar.readLine().toUpperCase().trim();
}
}
//cerramos flujos de entrada y de salida y flujo estandar de entrada
fsalida.close();
fentrada.close();
f_stadar.close();
//cerramos socket
cliente.close();
}
public static void imprimirMensaje(DataInputStream fentrada, DataOutputStream fsalida)
{
try
{
//solo para uno
System.out.println("mensaje recibido: "+fentrada.readUTF());
//para imprimir en todos los sockets
// boolean var=true;int x=0;
// while(var)
// {
// System.out.println("mensaje recibido: "+fentrada.readUTF());
//
// if(x<(arraySockets.size()-1))
// {
// var=true;
// }
// else
// {
// var=false;
// }
// x++;
//
// }
}
catch (IOException e)
{
e.getMessage();
}
}
}
Guenas.
Te falta la clase que hace de servidor. Me gustaria ver como se crean los hilos.
Por otra parte no entiendo que haces pasandole al hilo un array de sockets
El hilo solo deberia tratar un único socket
Otra cosa es la nomenclatura. Para seguir la norma de java la clase hilocliente debería llamarse HiloCliente, aunque saltarse la norma no debería provocar fallos.
Otra cosa. despues de mandar un mensaje completo usa output.flush().
Si quieres recibir lineas completas con readline() asegurate que las salidas terminen con un fin de linea. No estoy seguro de que writeUTF lo haga.
Un saludo
Muchas gracias por responder Paposo, lo intento mirar de esa manera y te comento.
esta es la clase servidor:
package trivial;
import java.io.*;
import java.net.*;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
public class server
{
//constante con el numero máximo de clientes
private final static int maximoClientes=4;
//array dinamico de sockets
static volatile ArrayList<Socket> arraySockets=new ArrayList<Socket>();
public static void main(String[] args)throws IOException
{
Socket sc;
//variable que recoja el número de cliente
int numCliente=0;
//puerto por el que realizaremos las operaciones
int puerto=5005;
ServerSocket s=new ServerSocket(puerto);
System.out.println("esperando a que se conecte algun cliente...");
while (numCliente<maximoClientes)
{
//esperamos la llegada de un cliente
sc = s.accept();
//guardo socket de nuevo cliente en el array
arraySockets.add(sc);
//creamos hilo y le madamos el socket en el constructor
hilocliente hc = new hilocliente(sc,arraySockets/*,arrayPregResp*/);
// try {
// hc.join();
// } catch (InterruptedException ex) {
// Logger.getLogger(servidor.class.getName()).log(Level.SEVERE, null, ex);
// }
//lanzamos hilo
hc.start();
//incrementamos en uno el número de cliente
numCliente++;
}
//Fin de juego
}
}
ooooo!!! funciona con lo que me comentaste! con "System.out.flush();" antes y despues de una operación de lectura.
Mil gracias!
ahora falla a partir de la primera pregunta, es decir, conecto dos usuarios y la primera pregunta-respuesta funciona, pero una vez se conesta la pregunta dos en uno de los dos, se desfasa.
Buenas tardes, estoy realizando un proyecto para clase en el que debo utilizar hilos de manera que la clase principal (servidor) espere a que ejecute clientes para asignarles un hilo y en ese punto empezar a enviar de una a una las preguntas de lo que sería un trivial.
Consigo que todo funcione solo si pongo en marcha un cliente pero si conecto 2 al mismo tiempo se desfasa. He intentado durante varios días todo lo que se me ha ocurrido sin un resultado demasiado favorable. ¿Alguien con una idea diferente? Les agradezco su tiempo de antemano. Un saludo.