Java - Sockets y nuevas clases

   
Vista:

Sockets y nuevas clases

Publicado por Josep (3 intervenciones) el 08/04/2014 19:53:55
He escrito un codigo para conectar un cliente y un servidor. Uso una primera pantalla creada con JFrame que me permite elegir diferentes opciones. Si pulsas el botón de "crear servidor" se crea una instancia de la clase ServerClass.

--Codigo MainClass-- (solo pongo lo relevante para ahorrar codigo y espacio, los include estan debidamente escritos)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class MainClass{
    public static void main(String arg[]){
        new MainClass();
    }
 
    public MainClass(){
        JFrame frame = new JFrame();
        JButton button = new JButton("Create the frame");
        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                ServerClass c = new ServerClass();
                c.run();
            }
        });
        frame.getContentPane().add(button);
        frame.pack();
        frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
}


--Codigo ServerClass--
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class ServerClass{
    public static void main(String arg[]){
        ServerClass c = new ServerClass();
        c.run();
    }
 
    public ServerClass(){
        createGUI();
    }
    private void createGUI(){
        JFrame frame = new JFrame("test frame");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(30, 30);
        frame.setVisible(true);
    }
    public void run(){
        ServerSocket serverSocket;
        try {
            serverSocket = new ServerSocket(60000);
            System.out.println("socket created");
            Socket s = serverSocket.accept();      <---Esta línea es la problematica
            s.close();
        } catch (IOException ex) {
            Logger.getLogger(ServerClass.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

El problema es que cuando corro el programa desde MainClass, se crea el JFrame de ServerClass al pulsar el botón, pero se queda colgada en la parte de serverSocket.accept(); y en este momento deja de funcionar el JFrame en si (si pulso la 'X' no se cierra, si lo redimensiono se queda negro....).
Por otro lado, si ejecuto el programa desde ServerClass funciona bien.
Seguramente es un fallo tonto que no logro encontrar, por esto lo posteo aquí.

En algun momento el programa MainClass me lanzó una excepción tipo "NoClassDefFound".
¿Puede ser este el problema?

Agradezco la ayuda de antemano
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder

Sockets y nuevas clases

Publicado por Tom (914 intervenciones) el 09/04/2014 11:34:33
Hay muchísimos tutoriales de sockets por la red.
La propia documentación de serversocket es casi suficiente.
Básicamente, accept() (como en casi cualquier otra implementación de sockets) _espera_ a que un cliente se conecte. O sea, bloquea.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Sockets y nuevas clases

Publicado por Josep (3 intervenciones) el 09/04/2014 12:06:09
El problema no es el socket y la espera de una conexion, pues si uso el mismo programa iniciandolo desde ServerClass me funciona y al pulsar el boton de cerrar se cierra, pero al iniciarlo desde la otra clase se quedan colgados los 2 jFrame
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Sockets y nuevas clases

Publicado por Tom (914 intervenciones) el 09/04/2014 16:22:29
Como quieras.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Sockets y nuevas clases

Publicado por UnoPorAhi (128 intervenciones) el 09/04/2014 16:44:45
Se te queda congelado porque estas bloqueando el EDT. En este caso tienes que utilizar el executor, para lanzar el servidor en un segundo plano.

Echale un vistazo a esta presentacion:
http://fr.slideshare.net/Ashberk/best-practices-in-java-and-swing


Un saludo
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
1
Comentar

Sockets y nuevas clases

Publicado por Josep (3 intervenciones) el 10/04/2014 12:58:00
Muchas gracias, esto ha resuelto el problema.
Corregidme si me equivoco:
Por lo que he entendido, el EDT es lo que controla todos los eventos de raton, teclado... de java. Al crear el servidor en el mismo hilo que el MainClass el EDT se quedaba colgado en el button que habia pulsado, y por esto no respondia a las otras acciones.
He buscado esto de los executors, pero lo he visto un poco dificil y lo he dejado para cuando tenga mas tiempo, pero he notado que es basicamente algo para ejecutar threads? y he usado simplemente un runnable y un thread para lanzarlo.

Ahora mi botón llama a esta funcion:
1
2
3
4
5
6
7
8
9
10
11
private void newServer(){
        Runnable miRunnable = new Runnable(){
            @Override
            public void run() {
                ServerClass s = new ServerClass();
                s.run();
            }
        };
        Thread server = new Thread(miRunnable);
        server.start();
    }
y funciona perfectamente.
Gracias
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Sockets y nuevas clases

Publicado por UnoPorAhi (128 intervenciones) el 10/04/2014 14:04:09
Si, el executor es similar a los threads aunque un poco mas controlado y puede dar mas rendimiento pues getiona un pool, pero tu solucion funciona perfectamente tambien.

Eso si, si desde tu thread en algun momento necesitas interactuar con la interfaz grafica entonces tienes que hacer que este codigo se ejecute dentro del hilo EDT. En ese caso debe usar un SwingWorker, que tambien es otro tipo de thread.

El EDT es un hilo que se encarga de gestionar la interfaz grafica de swing. Esta constantemente a la escucha de eventos, por lo que si le haces ejecutar un proceso pesado, vas a bloquear dicho hilo y la aplicacion, al no poder procesar eventos, no respondera.

http://www.javapractices.com/topic/TopicAction.do?Id=153


Un saludo
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar