Vous êtes sur la page 1sur 10

[cdigo] Conexiones Cliente-Servidor mediante sockets en Java

2tweetsretweet Por falta de tiempo me es imposible explicar este cdigo detalladamente, tal como me gustara, pero no tengo otra opcin que simplemente ponerlo. An as es de recordar que pueden dejar todos los comentarios que deseen, con sus dudas y sugerencias (que no pedidos de tareas). An as explico un poco el resultado del programa el programa es un chat simple (muy simple), que usa Sockets para crear conexiones de red. Consta de un servidor (Servidor.java) y un cliente (Cliente.java), mediante los cuales se puede establecer una conversacin. Si se escribe TERMINAR (sin comillas), la conexin se cierra.

El resultado

El cdigo
El cdigo fuente de Servidor.java: ? 001import java.io.*; import java.net.*; 002import java.awt.*; 003import java.awt.event.*; 004import javax.swing.*; 005 006public class Servidor extends JFrame { 007 private JTextField campoIntroducir; private JTextArea areaPantalla; 008 private ObjectOutputStream salida; 009 private ObjectInputStream entrada; 010 private ServerSocket servidor; 011 private Socket conexion; private int contador = 1; 012 013 // configurar GUI 014 public Servidor() 015 { super( "Servidor" ); 016 017 Container contenedor = getContentPane(); 018 019 // crear campoIntroducir y registrar componente de escucha 020 campoIntroducir = new JTextField(); 021 campoIntroducir.setEditable( false ); campoIntroducir.addActionListener( 022 new ActionListener() { 023 024 // enviar mensaje al cliente 025 public void actionPerformed( ActionEvent evento ) 026 { 027 enviarDatos( evento.getActionCommand() ); campoIntroducir.setText( "" ); 028 } 029 } 030 ); 031 032 contenedor.add( campoIntroducir, BorderLayout.NORTH );

033 // crear areaPantalla 034 areaPantalla = new JTextArea(); 035 contenedor.add( new JScrollPane( areaPantalla ), 036 BorderLayout.CENTER ); 037 038 setSize( 300, 150 ); setVisible( true ); 039 040 041 } // fin del constructor de Servidor 042 043 // configurar y ejecutar el servidor public void ejecutarServidor() 044 { 045 // configurar servidor para que reciba conexiones; procesar las conexiones 046 try { 047 048 // Paso 1: crear un objeto ServerSocket. 049 servidor = new ServerSocket( 12345, 100 ); 050 051 while ( true ) { 052 try { 053 esperarConexion(); // Paso 2: esperar una conexin. 054 obtenerFlujos(); // Paso 3: obtener flujos de 055entrada y salida. 056 procesarConexion(); // Paso 4: procesar la conexin. 057 } 058 // procesar excepcin EOFException cuando el cliente 059 cierre la conexin 060 catch ( EOFException excepcionEOF ) { 061 System.err.println( "El servidor termin la 062conexin" ); 063 } 064 finally { 065 cerrarConexion(); // Paso 5: cerrar la conexin. 066 ++contador; 067 } 068 069 } // fin de instruccin while 070 } // fin del bloque try 071 072 // procesar problemas con E/S 073 catch ( IOException excepcionES ) { 074 excepcionES.printStackTrace(); 075 } 076 077 } // fin del mtodo ejecutarServidor 078 079 // esperar que la conexin llegue, despus mostrar informacin 080de la conexin private void esperarConexion() throws IOException 081 { 082 mostrarMensaje( "Esperando una conexin\n" );

conexion = servidor.accept(); // permitir al servidor aceptar 083 la conexin 084 mostrarMensaje( "Conexin " + contador + " recibida de: " + 085 conexion.getInetAddress().getHostName() ); 086 } 087 088 // obtener flujos para enviar y recibir datos 089 private void obtenerFlujos() throws IOException 090 { // establecer flujo de salida para los objetos 091 salida = new ObjectOutputStream( conexion.getOutputStream() ); 092 salida.flush(); // vaciar bfer de salida para enviar 093informacin de encabezado 094 // establecer flujo de entrada para los objetos 095 entrada = new ObjectInputStream( conexion.getInputStream() ); 096 097 mostrarMensaje( "\nSe recibieron los flujos de E/S\n" ); 098 } 099 100 // procesar la conexin con el cliente 101 private void procesarConexion() throws IOException 102 { // enviar mensaje de conexin exitosa al cliente 103 String mensaje = "Conexin exitosa"; 104 enviarDatos( mensaje ); 105 // habilitar campoIntroducir para que el usuario del servidor 106 pueda enviar mensajes 107 establecerCampoTextoEditable( true ); 108 109 do { // procesar los mensajes enviados por el cliente 110 111 // leer el mensaje y mostrarlo en pantalla 112 try { mensaje = ( String ) entrada.readObject(); 113 mostrarMensaje( "\n" + mensaje ); 114 } 115 116 // atrapar problemas que pueden ocurrir al tratar de leer 117del cliente catch ( ClassNotFoundException excepcionClaseNoEncontrada ) 118 { 119 120desconocido"mostrarMensaje( "\nSe recibi un tipo de objeto ); 121 } 122 123 } while ( !mensaje.equals( "CLIENTE>>> TERMINAR" ) ); 124 125 } // fin del mtodo procesarConexion 126 127 // cerrar flujos y socket private void cerrarConexion() 128 { 129 mostrarMensaje( "\nFinalizando la conexin\n" ); establecerCampoTextoEditable( false ); // deshabilitar 130 campoIntroducir 131 132 try {

salida.close(); 133 entrada.close(); 134 conexion.close(); 135 } 136 catch( IOException excepcionES ) { excepcionES.printStackTrace(); 137 } 138 139 } 140 // enviar mensaje al cliente 141 private void enviarDatos( String mensaje ) 142 { // enviar objeto al cliente 143 try { 144 salida.writeObject( "SERVIDOR>>> " + mensaje ); 145 salida.flush(); 146 mostrarMensaje( "\nSERVIDOR>>> " + mensaje ); } 147 148 // procesar problemas que pueden ocurrir al enviar el objeto 149 catch ( IOException excepcionES ) { 150 areaPantalla.append( "\nError al escribir objeto" ); 151 } 152 } 153 154 // mtodo utilitario que es llamado desde otros subprocesos para 155manipular a // areaPantalla en el subproceso despachador de eventos 156 private void mostrarMensaje( final String mensajeAMostrar ) 157 { 158 // mostrar mensaje del subproceso de ejecucin despachador de eventos 159 SwingUtilities.invokeLater( 160 new Runnable() { // clase interna para asegurar que la GUI 161se actualice apropiadamente 162 163 public void run() // actualiza areaPantalla { 164 areaPantalla.append( mensajeAMostrar ); 165 areaPantalla.setCaretPosition( 166 areaPantalla.getText().length() ); 167 } 168 169 } // fin de la clase interna 170 ); // fin de la llamada a SwingUtilities.invokeLater 171 172 } 173 // mtodo utilitario que es llamado desde otros subprocesos para 174manipular a 175 // campoIntroducir en el subproceso despachador de eventos 176 private void establecerCampoTextoEditable( final boolean editable 177) 178 { // mostrar mensaje del subproceso de ejecucin despachador de 179eventos 180 SwingUtilities.invokeLater( new Runnable() { // clase interna para asegurar que la GUI 181 se actualice apropiadamente 182

public void run() // establece la capacidad de 183 modificar a campoIntroducir 184 { 185 campoIntroducir.setEditable( editable ); 186 } 187 } // fin de la clase interna 188 189 ); // fin de la llamada a SwingUtilities.invokeLater 190 } 191 192 public static void main( String args[] ) 193 { 194 JFrame.setDefaultLookAndFeelDecorated(true); Servidor aplicacion = new Servidor(); 195 aplicacion.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); 196 aplicacion.ejecutarServidor(); 197 } 198 199} // fin de la clase Servidor 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215

El cdigo fuente de Cliente.java: ? 001import java.io.*; import java.net.*; 002import java.awt.*; 003import java.awt.event.*; 004import javax.swing.*; 005 006public class Cliente extends JFrame { private JTextField campoIntroducir; 007 private JTextArea areaPantalla; 008 private ObjectOutputStream salida; 009 private ObjectInputStream entrada; 010 private String mensaje = ""; 011 private String servidorChat; private Socket cliente; 012 013 // inicializar servidorChat y configurar GUI

014 public Cliente( String host ) 015 { super( "Cliente" ); 016 017 servidorChat = host; // establecer el servidor al que se va a 018conectar este cliente 019 Container contenedor = getContentPane(); 020 021 // crear campoIntroducir y registrar componente de escucha 022 campoIntroducir = new JTextField(); 023 campoIntroducir.setEditable( false ); 024 campoIntroducir.addActionListener( 025 new ActionListener() { 026 // enviar mensaje al servidor 027 public void actionPerformed( ActionEvent evento ) 028 { 029 enviarDatos( evento.getActionCommand() ); 030 campoIntroducir.setText( "" ); } 031 } 032 ); 033 034 contenedor.add( campoIntroducir, BorderLayout.NORTH ); 035 036 // crear areaPantalla 037 areaPantalla = new JTextArea(); contenedor.add( new JScrollPane( areaPantalla ), 038 BorderLayout.CENTER ); 039 040 setSize( 300, 150 ); 041 setVisible( true ); 042 043 } // fin del constructor de Cliente 044 045 // conectarse al servidor y procesar mensajes del servidor 046 private void ejecutarCliente() 047 { // conectarse al servidor, obtener flujos, procesar la 048conexin 049 try { conectarAServidor(); // Paso 1: crear un socket para 050 realizar la conexin 051 // Paso 2: obtener los flujos de 052entrada yobtenerFlujos(); salida 053 procesarConexion(); // Paso 3: procesar la conexin 054 } 055 // el servidor cerr la conexin 056 catch ( EOFException excepcionEOF ) { 057 System.err.println( "El cliente termino la conexin" ); 058 } 059 060 // procesar los problemas que pueden ocurrir al comunicarse 061con el servidor catch ( IOException excepcionES ) { 062 excepcionES.printStackTrace(); 063 }

064 finally { 065 cerrarConexion(); // Paso 4: cerrar la conexin 066 } 067 068 } // fin del mtodo ejecutarCliente 069 070 // conectarse al servidor 071 private void conectarAServidor() throws IOException 072 { mostrarMensaje( "Intentando realizar conexin\n" ); 073 074 // crear Socket para realizar la conexin con el servidor 075 cliente = new Socket( InetAddress.getByName( servidorChat ), 07612345 ); 077 // mostrar la informacin de la conexin 078 mostrarMensaje( "Conectado a: " + 079 cliente.getInetAddress().getHostName() ); 080 } 081 082 // obtener flujos para enviar y recibir datos 083 private void obtenerFlujos() throws IOException 084 { // establecer flujo de salida para los objetos 085 salida = new ObjectOutputStream( cliente.getOutputStream() ); 086 salida.flush(); // vacar bfer de salida para enviar 087informacin de encabezado 088 // establecer flujo de entrada para los objetos 089 entrada = new ObjectInputStream( cliente.getInputStream() ); 090 091 mostrarMensaje( "\nSe recibieron los flujos de E/S\n" ); 092 } 093 094 // procesar la conexin con el servidor 095 private void procesarConexion() throws IOException 096 { // habilitar campoIntroducir para que el usuario del cliente 097 pueda enviar mensajes 098 establecerCampoTextoEditable( true ); 099 100 do { // procesar mensajes enviados del servidor 101 // leer mensaje y mostrarlo en pantalla 102 try { 103 mensaje = ( String ) entrada.readObject(); 104 mostrarMensaje( "\n" + mensaje ); 105 } 106 107 // atrapar los problemas que pueden ocurrir al leer del servidor 108 catch ( ClassNotFoundException excepcionClaseNoEncontrada ) 109 { 110 mostrarMensaje( "\nSe recibi un objeto de tipo 111desconocido" ); } 112 113

} while ( !mensaje.equals( "SERVIDOR>>> TERMINAR" ) ); 114 115 116 } // fin del mtodo procesarConexion 117 // cerrar flujos y socket 118 private void cerrarConexion() 119 { mostrarMensaje( "\nCerrando conexin" ); 120 establecerCampoTextoEditable( false ); // deshabilitar 121 campoIntroducir 122 123 try { 124 salida.close(); 125 entrada.close(); cliente.close(); 126 } 127 catch( IOException excepcionES ) { 128 excepcionES.printStackTrace(); 129 } 130 } 131 132 // enviar mensaje al servidor 133 private void enviarDatos( String mensaje ) { 134 // enviar objeto al servidor 135 try { salida.writeObject( "CLIENTE>>> " + mensaje ); 136 salida.flush(); 137 mostrarMensaje( "\nCLIENTE>>> " + mensaje ); 138 } 139 140 // procesar los problemas que pueden ocurrir al enviar el 141objeto catch ( IOException excepcionES ) { 142 areaPantalla.append( "\nError al escribir el objeto" ); 143 } 144 } 145 146 // mtodo utilitario que es llamado desde otros subprocesos para 147manipular a 148 // areaPantalla en el subproceso despachador de eventos 149 private void mostrarMensaje( final String mensajeAMostrar ) { 150 // mostrar mensaje del subproceso de ejecucin de la GUI 151 SwingUtilities.invokeLater( new Runnable() { // clase interna para asegurar que la GUI 152 153se actualice apropiadamente 154 public void run() // actualiza areaPantalla 155 { 156 areaPantalla.append( mensajeAMostrar ); areaPantalla.setCaretPosition( 157 areaPantalla.getText().length() ); 158 } 159 160 } // fin de la clase interna 161 162 ); // fin de la llamada a SwingUtilities.invokeLater 163 }

164 165 // mtodo utilitario que es llamado desde otros subprocesos para 166manipular a // campoIntroducir en el subproceso despachador de eventos 167 private void establecerCampoTextoEditable( final boolean editable 168) 169 { // mostrar mensaje del subproceso de ejecucin de la GUI 170 SwingUtilities.invokeLater( 171 new Runnable() { // clase interna para asegurar que la GUI 172se actualice apropiadamente 173 174 public void run() // establece la capacidad de 175modificar campoIntroducir { 176 campoIntroducir.setEditable( editable ); 177 } 178 179 } // fin de la clase interna 180 ); // fin de la llamada a SwingUtilities.invokeLater 181 } 182 183 184 public static void main( String args[] ) { 185 JFrame.setDefaultLookAndFeelDecorated(true); 186 Cliente aplicacion; 187 if ( args.length == 0 ) 188 aplicacion = new Cliente( "127.0.0.1" ); 189 else 190 aplicacion = new Cliente( args[ 0 ] ); 191 192 aplicacion.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); 193 aplicacion.ejecutarCliente(); 194 } 195 196} // fin de la clase Cliente 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211

Vous aimerez peut-être aussi