elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.
 
Inicio Ayuda Buscar Ingresar Registrarse
28 Mayo 2012, 01:59  


Tema destacado: Deseas probar algunas mejoras a la interfaz del foro? Prueba cake! acerca de

+  Foro de elhacker.net
|-+  Programación
| |-+  Programación General
| | |-+  Java (Moderadores: Debci, Leyer)
| | | |-+  Error tonto con threads y sockets
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] 2 Ir Abajo Respuesta Imprimir
Autor Tema: Error tonto con threads y sockets  (Leído 4,627 veces)
Debci
Moderador
***
Desconectado Desconectado

Mensajes: 1.945


Actualizate o muere!


Ver Perfil WWW
Error tonto con threads y sockets
« en: 26 Diciembre 2009, 15:39 »

Hola a todos jeje, soy yo otra vez, he vuelto al java xD
Mirad estoy constryendo una aplicacion con sockets, que gestiona varios cliente mediante el uso de threads, la cosa esta en que cada vez que se conecta un cliente al servidor, este le abre un thread, y lo deja en ejecucion hasta que el cliente se cierra y le envia un binario, cuando le envia el binario se cumple el bucle y el thread muere, pero ocurre una cosa extraña, mirad el codigo:

ClienteGui.java
Código
 
package sockets;
 
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;
 
/**
*
* @author debci
*/

public class ClienteGui extends javax.swing.JFrame {
           public static Socket socket;
           public static InputStream is;
           public static OutputStream os;
           public static DataInputStream dis;
           public static DataOutputStream dos;
   /** Creates new form ClienteGui */
   public ClienteGui() {
       initComponents();
   }
 
   /** This method is called from within the constructor to
    * initialize the form.
    * WARNING: Do NOT modify this code. The content of this method is
    * always regenerated by the Form Editor.
    */

   @SuppressWarnings("unchecked")
   // <editor-fold defaultstate="collapsed" desc="Generated Code">
   private void initComponents() {
 
       jButton1 = new javax.swing.JButton();
       jScrollPane1 = new javax.swing.JScrollPane();
       textoEnv = new javax.swing.JTextArea();
 
       setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
       addWindowListener(new java.awt.event.WindowAdapter() {
           public void windowClosed(java.awt.event.WindowEvent evt) {
               formWindowClosed(evt);
           }
           public void windowClosing(java.awt.event.WindowEvent evt) {
               formWindowClosing(evt);
           }
       });
 
       jButton1.setText("Enviar");
       jButton1.addActionListener(new java.awt.event.ActionListener() {
           public void actionPerformed(java.awt.event.ActionEvent evt) {
               jButton1ActionPerformed(evt);
           }
       });
 
       textoEnv.setColumns(20);
       textoEnv.setRows(5);
       jScrollPane1.setViewportView(textoEnv);
 
       javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
       getContentPane().setLayout(layout);
       layout.setHorizontalGroup(
           layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
           .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
               .addContainerGap(337, Short.MAX_VALUE)
               .addComponent(jButton1)
               .addContainerGap())
           .addGroup(layout.createSequentialGroup()
               .addGap(21, 21, 21)
               .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
               .addContainerGap(117, Short.MAX_VALUE))
       );
       layout.setVerticalGroup(
           layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
           .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
               .addContainerGap(89, Short.MAX_VALUE)
               .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
               .addGap(83, 83, 83)
               .addComponent(jButton1)
               .addContainerGap())
       );
 
       pack();
   }// </editor-fold>
 
   private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
       try {
           String cadena = textoEnv.getText();
           dos.writeBoolean(true);
           dos.writeUTF(cadena);
 
       } catch (IOException ex) {
           Logger.getLogger(ClienteGui.class.getName()).log(Level.SEVERE, null, ex);
       }
   }
 
   private void formWindowClosed(java.awt.event.WindowEvent evt) {
 
   }
 
   private void formWindowClosing(java.awt.event.WindowEvent evt) {
       try {
           dos.writeBoolean(false);
       } catch (IOException ex) {
           Logger.getLogger(ClienteGui.class.getName()).log(Level.SEVERE, null, ex);
       }
   }
 
   /**
   * @param args the command line arguments
   */

   public static void main(String args[]) {
       java.awt.EventQueue.invokeLater(new Runnable() {
           public void run() {
               try {
                   new ClienteGui().setVisible(true);
                   socket = new Socket("localhost", 5557);
                   is = socket.getInputStream();
                   os = socket.getOutputStream();
                   dis = new DataInputStream(is);
                   dos = new DataOutputStream(os);
               } catch (IOException ex) {
                   Logger.getLogger(ClienteGui.class.getName()).log(Level.SEVERE, null, ex);
               }
           }
       });
   }
 
   // Variables declaration - do not modify
   private javax.swing.JButton jButton1;
   private javax.swing.JScrollPane jScrollPane1;
   private javax.swing.JTextArea textoEnv;
   // End of variables declaration
 
}
 
 


Servidor.java

Código
package sockets;
 
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import threads.ThreadServidor;
 
/**
*
* @author debci
*/

public class Servidor {
 
   public static void main(String[] args) throws IOException {
     Servidor servidor = new Servidor();
     servidor.ServidorChat();
 
   }
 
  public void ServidorChat()
   {
       try
       {
           ServerSocket socketServidor = new ServerSocket(5557);
 
           while (true)
           {
               System.out.println("Esperando conexiones...");
               Socket cliente = socketServidor.accept();
 
               Runnable nuevoCliente = new ThreadServidor(cliente);
               Thread hilo = new Thread(nuevoCliente);
               hilo.start();
 
           }
       } catch (Exception e)
       {
           e.printStackTrace();
       }
   }
}
 
 
 

ThreadServidor.java
Código
package threads;
 
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;
 
/**
*
* @author debci
*/

public class ThreadServidor extends Thread {
 
//Socket al que esta conectado el cliente
   private Socket socket1;
 
/** Para lectura de datos en el socket */
   private DataInputStream dataInput;
 
   /** Para escritura de datos en el socket */
   private DataOutputStream dataOutput;
 
   private boolean acabado = true;
 
 
   public ThreadServidor(Socket socket) {
       try {
           socket1 = socket;
           dataInput = new DataInputStream(socket.getInputStream());
           dataOutput = new DataOutputStream(socket.getOutputStream());
 
       } catch (IOException ex) {
 
           System.err.println("Error de procesamiento de datos: \n" + ex);
 
       }
   }
 
   public void run() {
       try {
         while(acabado){
           acabado = dataInput.readBoolean();
           String mensajeRecivido = dataInput.readUTF();
           System.out.println(mensajeRecivido + "\n");
 
         }
 
       } catch (IOException ex) {
           Logger.getLogger(ThreadServidor.class.getName()).log(Level.SEVERE, null, ex);
       }
 

Me explico, la cosa esta en que cuando el cliente, se cierra (formClosing) se envia el booleano al thread que lo esta atendiendo.
Si el booleano se cambia, se rompe el bucle while y se muere el thread.

El problema, y no se de donde viene, es que cuando cierro un cliente y le pido desconexion y que mate al thread, el servidor libera un error:

Código:
26-dic-2009 15:30:55 threads.ThreadServidor run
GRAVE: null
java.io.EOFException
        at java.io.DataInputStream.readUnsignedShort(DataInputStream.java:323)
        at java.io.DataInputStream.readUTF(DataInputStream.java:572)
        at java.io.DataInputStream.readUTF(DataInputStream.java:547)
        at threads.ThreadServidor.run(ThreadServidor.java:50)
        at java.lang.Thread.run(Thread.java:619)
Me da ese error y luego continua atendiendo clientes, cada vez que cierro un cliente me lo da, y no se porque es, y como comprendereis no quiero darle uso a una aplicacon que tiene un defecto claro.

Saludos y gracias a todos.


En línea

Leyer
Moderador
***
Desconectado Desconectado

Mensajes: 772


[]


Ver Perfil WWW
Re: Error tonto con threads y sockets
« Respuesta #1 en: 26 Diciembre 2009, 23:34 »

 :P si es verdad es un error tonto. te da ese error por que  no estas haciendo la comprobacion del cierre de conexion en el hilo usuario que estas creando en tu caso es ThreadServidor..

Saludos!


En línea

Debci
Moderador
***
Desconectado Desconectado

Mensajes: 1.945


Actualizate o muere!


Ver Perfil WWW
Re: Error tonto con threads y sockets
« Respuesta #2 en: 27 Diciembre 2009, 15:00 »

:P si es verdad es un error tonto. te da ese error por que  no estas haciendo la comprobacion del cierre de conexion en el hilo usuario que estas creando en tu caso es ThreadServidor..

Saludos!
Mmm comprovacion? a que te refieres, algun tipo de ping?

Saludos
En línea

panaka


Desconectado Desconectado

Mensajes: 511



Ver Perfil
Re: Error tonto con threads y sockets
« Respuesta #3 en: 27 Diciembre 2009, 16:45 »

Supongo que se referirar a que cuando intentas utilizar una conexion que has cerrado no has comprobado si efectivametne dicha coenxion esta bind, prueba.isConected(), .isBound()
Saludos
En línea




Chuck Norris es tan friki tan friki que ve la television en el osciloscopio
Debci
Moderador
***
Desconectado Desconectado

Mensajes: 1.945


Actualizate o muere!


Ver Perfil WWW
Re: Error tonto con threads y sockets
« Respuesta #4 en: 27 Diciembre 2009, 17:06 »

Gracias a todos, resuelto ^^
Para no abrir otro post, preguinto aqui mi nueva duda:
Como puedo hacer para que todo lo que envien todos los clientes, el servidor lo envie a todos, es decir, lo que un cliente envia a su thread en el servidor, el thread lo mande a los demas clientes, una sala de chat por asi decirlo, es que mi logica no llega a mas, no veo de que manera podria hacerlo.

Saludos y gracias a todos
En línea

Leyer
Moderador
***
Desconectado Desconectado

Mensajes: 772


[]


Ver Perfil WWW
Re: Error tonto con threads y sockets
« Respuesta #5 en: 27 Diciembre 2009, 18:35 »

muy facil tienes que hacer un vector o HasTable( lo recomiendo) donde almacenaras los hilos de los usuarios por su IP u otra referencia que puedas usar es decir HasTable.put("127.0.0.1",usuario); donde usuario es el objeto de hilo usuario que creas por cada conexion entrante al servidor  ..entonces cuando llega un mensaje el servidor solo tienes que leer todos los usuarios y eviarle el mensaje recibido a todos..ya que cada uno tendra su metodo de lectura y escritura (In/Out);)  tambien sirve para mensajes privados solo hay que usar un poco mas la logica :) espero te de la idea .asi lo ise en mi Jchat :D

Saludos

Edit:
Sobre lo anterior.
Yo me referia a que en el servidor no estabas creando la comprobacion del cierre es decir que cuando el cliente enviaba el boolean para cerrar..daba error en el hilo usuario del servidor por que no estaba la accion de dicha accion de cierre. if(!acabado) break;
« Última modificación: 27 Diciembre 2009, 18:58 por LEYER » En línea

Debci
Moderador
***
Desconectado Desconectado

Mensajes: 1.945


Actualizate o muere!


Ver Perfil WWW
Re: Error tonto con threads y sockets
« Respuesta #6 en: 27 Diciembre 2009, 19:01 »

muy facil tienes que hacer un vector o HasTable( lo recomiendo) donde almacenaras los hilos de los usuarios por su IP u otra referencia que puedas usar es decir HasTable.put("127.0.0.1",usuario); donde usuario es el objeto de hilo usuario que creas por cada conexion entrante al servidor  ..entonces cuando llega un mensaje el servidor solo tienes que leer todos los usuarios y eviarle el mensaje recibido a todos..ya que cada uno tendra su metodo de lectura y escritura (In/Out);)  tambien sirve para mensajes privados solo hay que usar un poco mas la logica :) espero te de la idea .asi lo ise en mi Jchat :D

Saludos

Edit:
Sobre lo anterior.
Yo me referia a que en el servidor no estabas creando la comprobacion del cierre es decir que cuando el cliente enviaba el boolean para cerrar..daba error en el hilo usuario del servidor por que no estaba la accion de dicha accion de cierre. if(!acabado) break;
Mira yo he pensado lo siguiente, a cada user una id, y a partir de esto le asigno un hilo a cada uno, pero se me plantea una duda, si meto la id con el hilo en la hashtable como escribo los streams solo con e hilo alamacenado?

Saludos
« Última modificación: 27 Diciembre 2009, 19:03 por ,.-~*´¨¯¨`*·~-.¸..::| D3Bć1 |::.,.-~*´¨¯¨`*·~-.¸ » En línea

Leyer
Moderador
***
Desconectado Desconectado

Mensajes: 772


[]


Ver Perfil WWW
Re: Error tonto con threads y sockets
« Respuesta #7 en: 27 Diciembre 2009, 19:11 »

bueno el obj usuario oviamente tienes que pasarle el socket solo tienes que hacer en el obj o hilo usuario los stream in/out la entrada puedes hacerla en el metodo run del obj usuario para recibir. creo que te refieres a eso.. 
En línea

Debci
Moderador
***
Desconectado Desconectado

Mensajes: 1.945


Actualizate o muere!


Ver Perfil WWW
Re: Error tonto con threads y sockets
« Respuesta #8 en: 27 Diciembre 2009, 20:02 »

bueno el obj usuario oviamente tienes que pasarle el socket solo tienes que hacer en el obj o hilo usuario los stream in/out la entrada puedes hacerla en el metodo run del obj usuario para recibir. creo que te refieres a eso.. 
Vale, mira, haber si me lo planteo:

Algoritmo:

Server escucha
Cliente activo [1]
Servidor Guarda en hashTable
Cliente activo [2]
Servidor guarda en HashTable
Cliente[1] escribe streamSocket
Servidor lee en el thread de ese cliente, y lo envia al bucle del servidor.
Servidor recorre hashTable (todos los indices) y saca uno a uno los sockets de estos para escribir el stream
Todos los cliente lo reciven.

Seria asi?

Buff y eso aguantar el servidor?
Que duro... y poderoso el lenguaje Java...

Bestial

Saludos
En línea

Leyer
Moderador
***
Desconectado Desconectado

Mensajes: 772


[]


Ver Perfil WWW
Re: Error tonto con threads y sockets
« Respuesta #9 en: 27 Diciembre 2009, 20:09 »

no saca los socket solo llama al metodo escritura y pues si es correpto el servidor funcionara bien ya lo veras
« Última modificación: 27 Diciembre 2009, 20:12 por LEYER » En línea

Debci
Moderador
***
Desconectado Desconectado

Mensajes: 1.945


Actualizate o muere!


Ver Perfil WWW
Re: Error tonto con threads y sockets
« Respuesta #10 en: 27 Diciembre 2009, 20:19 »

no saca los socket solo llama al metodo escritura y pues si es correpto el servidor funcionara bien ya lo veras
llamo al metodo de escritura sobre la hashTable? pero no deberia hacer lo siguiente:

for(int i = 0;length de hashtable; i++){
Socket socketVolatil = hashTable.getKey(o parecido)
socketVolatil.writeUtf(datosrecividosdeuncliente);
}

NO?

Saludos
En línea

Leyer
Moderador
***
Desconectado Desconectado

Mensajes: 772


[]


Ver Perfil WWW
Re: Error tonto con threads y sockets
« Respuesta #11 en: 27 Diciembre 2009, 20:26 »

tambien funciona pero mi recomendacion es que los hilos en si tengan su entrada y salida interna seria

hashTable.getKey(ID).metodoDeEscritura("texto");

class usuario extends Therad{
public void write(String text){
    ......
    }
}
class servidor {
....
socket.acept():
Usuario usuario = new Usuario(socket);
HastTable.put("ID",usuario);
usuario.start;
}
En línea

Debci
Moderador
***
Desconectado Desconectado

Mensajes: 1.945


Actualizate o muere!


Ver Perfil WWW
Re: Error tonto con threads y sockets
« Respuesta #12 en: 27 Diciembre 2009, 20:46 »

tambien funciona pero mi recomendacion es que los hilos en si tengan su entrada y salida interna seria

hashTable.getKey(ID).metodoDeEscritura("texto");

class usuario extends Therad{
public void write(String text){
    ......
    }
}
class servidor {
....
socket.acept():
Usuario usuario = new Usuario(socket);
HastTable.put("ID",usuario);
usuario.start;
}
Me da un nuevo problema... y no entiendo porque :s

Mira te lo enseño:

Cuando el servidor recive una nueva conexion, por tanto un nuevo cliente aumenta el contador de clientes, cuando este se va disminuye en uno el contador, asi que uso esas keys para identificarlos en la hashTable:

Código
 public void ServidorChat()
   {
       try
       {
           ServerSocket socketServidor = new ServerSocket(5558);
 
           while (true)
           {
               System.out.println("Esperando conexiones...");
               Socket cliente = socketServidor.accept();
               contador++;
               System.out.println("Bienvenid@ cliente numero " + contador + ".\n");
 
 
               Runnable nuevoCliente = new ThreadServidor(cliente);
               Thread hilo = new Thread(nuevoCliente);
               hilo.start();
               System.out.println("Te hemos asignado el thread: " + hilo + ".\n");
               vextorClientes.put(contador, socket);
 
 
           }
       } catch (Exception e)
       {
           e.printStackTrace();
       }
   }
 
Y ahi em da error al ejecutar, es decir, cuando recivo una nueva conexion y guardo los datos del cliente en el vector (HashTable), me da el siguiente error:

Esperando conexiones...
java.lang.NullPointerException
Bienvenid@ cliente numero 1.
        at threads.ThreadServidor.<init>(ThreadServidor.java:41)
        at sockets.Servidor.ServidorChat(Servidor.java:41)
        at sockets.Servidor.main(Servidor.java:23)


En la linea que marca error tengo el HashTable que reocje el socket y la clave.
Porque? no lo se...


Saludos
En línea

Leyer
Moderador
***
Desconectado Desconectado

Mensajes: 772


[]


Ver Perfil WWW
Re: Error tonto con threads y sockets
« Respuesta #13 en: 27 Diciembre 2009, 21:16 »

en fragmento no veo nada malo :P a no ser que el hastTable no este definido HastTable<Integer,Socket> tambien creo que tu ThreadServidor era Thread y lo estas pasando a runable para luego a Thread eso no es bueno. por lo demas no veo el error en ese fragmento
En línea

Debci
Moderador
***
Desconectado Desconectado

Mensajes: 1.945


Actualizate o muere!


Ver Perfil WWW
Re: Error tonto con threads y sockets
« Respuesta #14 en: 27 Diciembre 2009, 21:47 »

en fragmento no veo nada malo :P a no ser que el hastTable no este definido HastTable<Integer,Socket> tambien creo que tu ThreadServidor era Thread y lo estas pasando a runable para luego a Thread eso no es bueno. por lo demas no veo el error en ese fragmento
osea que el paso a runable lo puedo quitar y ejecutar directamente el thread?
Edito:
Ahora he declarado la hastable como me has dicho y hay otro error:

Esperando conexiones...
Bienvenid@ cliente numero 1.

java.lang.NullPointerException
Te hemos asignado el thread: Thread[Thread-1,5,main].
        at sockets.Servidor.ServidorChat(Servidor.java:45)
        at sockets.Servidor.main(Servidor.java:23)


Adios cliente 1

No veo porque ocurre pero weno...

Saludos

EDITO:
Solucionado, hacia falta instanciar el obejto mediante el operador new:
Código
public static Hashtable<Integer,Socket> vectorClientes = new Hashtable();
 

Ahoraaa si, voy a probar con el metodo que me dijiste.
Me parece increible que se peuda automatizar una tarea tan compleja, crear microprocesos para cada cliente y que etsen activos todo el rato atendiendo a sus clientes, que se recorran las listas de clientes y se envien datos...

Cada vez es mas flipante.

Saludos
« Última modificación: 27 Diciembre 2009, 21:56 por ,.-~*´¨¯¨`*·~-.¸..::| D3Bć1 |::.,.-~*´¨¯¨`*·~-.¸ » En línea

Páginas: [1] 2 Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
[Sockets] - Error en BIND
Programación C/C++
farresito 2 686 Último mensaje 26 Abril 2011, 19:52
por farresito
[AYUDA] Error en sockets
Programación C/C++
goro_333 6 151 Último mensaje 20 Mayo 2012, 22:56
por goro_333
Powered by SMF 1.1.16 | SMF © 2006-2008, Simple Machines