Java - Uso de sockets

 
Vista:
sin imagen de perfil

Uso de sockets

Publicado por Victor (18 intervenciones) el 07/11/2021 12:09:50
Buenas tardes estoy probando el uso de sockets y en este ejemplo tengo un servidor y dos clientes.
Uno de los clientes correo desde el host al igual que el servidor y el otro cliente desde una maquina virtual de ubuntu.
Dentro de cada cliente pongo la ip hacia a donde va el mensaje pasa por el servidor y deberia llegar al otro cliente.
El codigo del Servidor es este:
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
package Socket;
 
import java.awt.BorderLayout;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.net.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
 
/**
 *
 * @author Victor
 */
public class Servidor {
 
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
 
        marcoSocketServidor miMarco = new marcoSocketServidor();
        miMarco.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 
    }
 
}
 
class marcoSocketServidor extends JFrame implements Runnable {
 
    marcoSocketServidor() {
 
        setBounds(100, 100, 260, 400);
 
        JPanel miLamina = new JPanel();
 
        miLamina.setLayout(new BorderLayout());
 
        entradaTexto = new JTextArea();
 
        miLamina.add(entradaTexto);
 
        add(miLamina);
        setVisible(true);
 
        Thread hilo = new Thread(this);
        hilo.start();
 
    }
 
    @Override
    public void run() {
 
        try {
            ServerSocket miServidor = new ServerSocket(6000);
 
            String ip, nick, mensaje;
 
            PaqueteEnvio paquete_recibido = new PaqueteEnvio();
            //Queda a la escucha de las peticiones por el puerto que se a usado en su creacion
 
            while (true) {
                Socket miSocket = miServidor.accept();
 
                ObjectInputStream flujoEntrada = new ObjectInputStream(miSocket.getInputStream());
 
                paquete_recibido = (PaqueteEnvio) flujoEntrada.readObject();
 
                nick = paquete_recibido.getNick();
 
                ip = paquete_recibido.getIp();
 
                mensaje = paquete_recibido.getMensaje();
 
                entradaTexto.append("\n" + nick + ": " + mensaje + " IP: " + ip);
 
                //-----------PARA REENVIAR EL PAQUETE RECIBIDO
                //para la respuesta del servidor se usa la misma IP con diferente puerto
                Socket socketReenvio = new Socket(ip, 9090);
 
                ObjectOutputStream paqueteReenvio = new ObjectOutputStream(socketReenvio.getOutputStream());
 
                paqueteReenvio.writeObject(paquete_recibido);
 
                paqueteReenvio.close();
                flujoEntrada.close();
 
                socketReenvio.close();
                miSocket.close();
 
            }
 
        } catch (IOException ex) {
            System.out.println("Error IOException: " + ex.getMessage());
        } catch (ClassNotFoundException ex) {
            System.out.println("Error ClassNotFoundException: " + ex.getMessage());
        }
 
    }
 
    private JTextArea entradaTexto;
 
}

Y el del cliente es este:
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
package Socket;
 
import java.awt.BorderLayout;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import java.net.*;
import java.io.*;
import java.util.logging.Level;
import java.util.logging.Logger;
 
/**
 *
 * @author Victor
 */
public class Cliente {
 
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
 
        marcoSocketCliente miMarco = new marcoSocketCliente();
        miMarco.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 
    }
 
}
 
class marcoSocketCliente extends JFrame {
 
    marcoSocketCliente() {
 
        setBounds(100, 100, 250, 400);
 
        laminaSocketCliente miLamina = new laminaSocketCliente();
 
        add(miLamina);
        setVisible(true);
 
    }
}
 
class laminaSocketCliente extends JPanel implements Runnable {
 
    laminaSocketCliente() {
 
        nick = new JTextField("Nick");
        add(nick);
 
        chat = new JLabel("-CHAT-");
        add(chat);
 
        ip = new JTextField("192.168.1.30");
        add(ip);
 
        areaChat = new JTextArea(12, 20);
        add(areaChat);
 
 
        entradaTexto = new JTextField(20);
        add(entradaTexto);
 
        btEnviar = new JButton("Enviar");
        btEnviar.addActionListener(new EnviarTexto());
        add(btEnviar);
 
        Thread miHiloCliente = new Thread(this);
 
        miHiloCliente.start();
    }
 
    private class EnviarTexto implements ActionListener {
 
        @Override
        public void actionPerformed(ActionEvent ae) {
 
            try {
                //CREACION SOKET
                Socket miSoket = new Socket("192.168.1.30", 6000);
 
                if (miSoket.isConnected()) {
                    System.out.println("Conectado");
                }
 
                PaqueteEnvio datos = new PaqueteEnvio();
 
                datos.setNick(nick.getText());
 
                datos.setIp(ip.getText());
 
                datos.setMensaje(entradaTexto.getText());
 
                ObjectOutputStream paquete_datos = new ObjectOutputStream(miSoket.getOutputStream());
 
                paquete_datos.writeObject(datos);
 
                miSoket.close();
 
                paquete_datos.close();
 
            } catch (IOException ex) {
                System.out.print("Error IOException=>" + ex.getMessage());
            }
        }
 
    }
 
    @Override
    public void run() {
 
        try {
 
            ServerSocket serverSocketCliente = new ServerSocket(9090);
 
            PaqueteEnvio paqueteRecibido;
 
            Socket socketResuestaServidor;
 
            while (true) {
 
                socketResuestaServidor = serverSocketCliente.accept();
 
                ObjectInputStream respuestaSeridor = new ObjectInputStream(socketResuestaServidor.getInputStream());
                paqueteRecibido = (PaqueteEnvio) respuestaSeridor.readObject();
 
                areaChat.append("\n " + paqueteRecibido.getNick() + ": " + paqueteRecibido.getMensaje() + " IP: " + paqueteRecibido.getIp());
 
            }
 
            //
        } catch (Exception e) {
            System.out.println("Excepcion dentro del RunCliente=> " + e.getMessage());
        }
    }
    private JLabel chat;
    private JTextField entradaTexto, ip, nick;
    private JButton btEnviar;
    private JTextArea areaChat;
    private InetAddress direccion;
}
 
class PaqueteEnvio implements Serializable {
 
    public String getIp() {
        return ip;
    }
 
    public void setIp(String ip) {
        this.ip = ip;
    }
 
    public String getNick() {
        return nick;
    }
 
    public void setNick(String nick) {
        this.nick = nick;
    }
 
    public String getMensaje() {
        return mensaje;
    }
 
    public void setMensaje(String mensaje) {
        this.mensaje = mensaje;
    }
 
    private String ip, nick, mensaje;
}

La aplicacion cliente que está en el host me manda este error:
Error IOException: connect: Address is invalid on local machine, or port is not valid on remote machine


Alguna idea?
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

Uso de sockets

Publicado por Tom (1831 intervenciones) el 07/11/2021 17:23:43
Para este tipo de cosas en lugar de estar abriendo, conectando, y cerrando sockets por cada mensaje es bastante mejor usar UDP (DatagramSocket).
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

Uso de sockets

Publicado por Tom (1831 intervenciones) el 07/11/2021 17:55:43
Por lo demás parece que funciona, siempre y cuando la IP (local) de tu servidor sea la 192.168.1.30 ¿ lo has comprobado ?
Haces cosas muy poco ortodoxas ... no deberías crear los Threads desde las clases del UI ... deberías hacerlo desde el hilo principal (dónde se ejecuta main()) o bien usar SwingWorker o así ...

Además ... deberías dejar los sockets abiertos (y el ObjectOutputStream) hasta que cierres la aplicación (los sockets pueden tener un tiempo de espera en el SO desde que se cierra el socket hasta que se libera realmente el port).

Ah! Y el mismo socket del cliente que usas para enviar lo puedes usar para recibir, no es necesario que el cliente tenga su propio serversocket (ni que el server se reconecte al cliente).
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
sin imagen de perfil

Uso de sockets

Publicado por Victor (18 intervenciones) el 07/11/2021 18:25:09
Gracias por contestar.
Haré esos cambios que comentas.
Saludos.
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