Taller de Prácticas : Cliente y Servidor TCP en Java

Escrito por Sergio De Luz
GNU Linux
4

Os presento una aplicación hecha en Java por mí.

Consiste en un Cliente / Servidor TCP muy sencillo, el funcionamiento es el siguiente:

– En el cliente ponemos una palabra, el servidor la leerá y la transformará en mayúsculas, a continuación el servidor se la manda al cliente junto con la IP y el puerto usado por el cliente.
– Podremos elegir los puertos a usar con el comando p, si no ponemos puerto, se pondrá por defecto el 2510.

Se tratan excepciones y control de errores, si activamos el cliente antes de abrir el servidor nos saldrá la excepción, y así con todos los demás posibles errores que nos vayamos a encontrar.

El código no es, ni mucho menos perfecto, siempre se puede mejorar, pero espero que os de una idea de lo que hay que hacer para hacer por ejemplo, un cliente / servidor FTP…o un cliente de email.

Modo de ejecución (GNU/Linux) del SERVIDOR:

Compilar:

javac TCPServidor.java

Ejecutar:

java TCPServidor
ó
java TCPServidor p <puerto>

Código:


import java.io.*;
 import java.net.*;
 class TCPServidor
 {

public static void main(String args[]) throws Exception
 {
 System.out.println("El servidor va a ponerse a la escucha, un momento mientras se leen los parametros");
 int port = 2510;
 if (args.length == 0 || args==null) {
 System.out.println("El puerto no se ha especificado, se usara el puerto por defecto: 2510");
 } else if (args[0].equals("p")) {
 port = Integer.parseInt(args[1]);
 System.out.println("Vamos a usar el puerto:"+port);
 }
 else    {
 System.out.println("Debes especificar la opcion p");
 }
 String fraseCliente;
 String fraseMayusculas;
 ServerSocket socketAtendido = null;
 try {
 socketAtendido = new ServerSocket(port);
 } catch (IOException e)
 {
 System.out.println("No se ha podido levantar el servidor");
 System.exit ( 0 );
 }
 System.out.println("Servidor a la escucha");
 while (true) {
 Socket socketConexion = null;
 try {
 socketConexion = socketAtendido.accept();
 } catch (IOException e)
 {
 System.out.println("No se ha podido crear el nuevo socket");
 }
 //devuelve lo introducido en el cliente pero en mayusculas
 BufferedReader entradaDesdeCliente = null;
 try {
 entradaDesdeCliente = new BufferedReader(new InputStreamReader(socketConexion.getInputStream()));
 } catch (IOException e)
 {
 System.out.println("Error en el flujo de datos de entrada");
 }

DataOutputStream salidaACliente = null;
 try {
 salidaACliente = new DataOutputStream(socketConexion.getOutputStream());
 } catch (IOException e)
 {
 System.out.println("Error en el flujo de datos de salida");
 }

fraseCliente = entradaDesdeCliente.readLine();
 fraseMayusculas = fraseCliente.toUpperCase() + 'n';
 salidaACliente.writeBytes(fraseMayusculas);
 //devuelve la direccion IP del cliente
 OutputStream aux = null;
 try {
 aux = socketConexion.getOutputStream();
 } catch (IOException e)
 {
 System.out.println("Error obtener socket");
 }
 DataOutputStream flujo = new DataOutputStream(aux);
 try {
 flujo.writeUTF ( "Tu direccion IP es:"+socketConexion.getInetAddress() );
 } catch (IOException e)
 {
 System.out.println("Error al escribir al cliente");
 }
 //devuelve el puerto usado por el cliente
 OutputStream aux2 = null;
 try {
 aux2 = socketConexion.getOutputStream();
 } catch (IOException e)
 {
 System.out.println("Error obtener socket");
 }
 DataOutputStream flujo2 = new DataOutputStream(aux2);
 try {
 flujo2.writeUTF ( "Tu puerto es:"+socketConexion.getLocalPort() );
 } catch (IOException e)
 {
 System.out.println("Error al escribir al cliente");
 }
 }
 }
 }

Si lo copiáis y pegáis, el código funcionará perfectamente y sin fallos.

Ahora vamos con el cliente:

Compilar:

javac TCPCliente.java

Ejecutar:

java TCPCliente.java d <DIRECCION IP> m <MENSAJE> p <PUERTO (OPCIONAL)>

Código:


import java.io.*;
 import java.net.*;

class TCPCliente {

public static void main(String args[]) {
 System.out.println("El cliente se pone en marcha, un momento mientras se leen los parametros");
 int port = 2510;
 String frase = null;
 String fraseModificada = null;
 String direccion = null;

if (args.length == 0 || args == null) {
 System.out.println("La direccion IP es obligatoria, el programa terminara");
 System.exit(0);
 } else if (args.length < 4) {
 // ERROR SIEMPRE: EL NUMERO DE ARGUMENTOS OBLIGATORIOS ES 4
 System.out.println("El numero de argumentos es erroneo, minimo direccion y palabra: d direccion m palabra");
 System.exit(0);

}

else if (args.length > 4) {

if (args[4].equals("p")) {
 if (args.length < 6) {

System.out.println("No se ha especificado puerto con opcion p; el programa terminara");
 System.exit(0);
 } else {
 port = Integer.parseInt(args[5]);
 }

System.out.println("Vamos a usar el puerto:" + port);

}
 }

if (args[0].equals("d")) {
 direccion = (args[1]);
 System.out.println("Vamos a usar la direccion IP:" + direccion);
 } else { // si no ponemos d, que es obligatorio, fallara
 System.out.println("El parametro debe ser d, el programa terminara");
 System.exit(0);
 }

if (args[2].equals("m")) {
 frase = args[3];
 } else {// si no ponemos m, que es obligatorio, fallara
 System.out.println("El parametro debe ser m, el programa terminara");
 System.exit(0);
 }

Socket socketCliente = null;
 try {
 socketCliente = new Socket(direccion, port);
 } catch (UnknownHostException e) {
 System.out.println("El host no existe");
 System.exit(0);
 } catch (IOException e) {
 System.out.println("***No se ha podido conectar: El host no esta levantado");
 System.exit(0);
 }
 DataOutputStream salidaServidor = null;
 try {
 salidaServidor = new DataOutputStream(socketCliente.getOutputStream());
 } catch (IOException e1) {
 System.out.println("No se ha podido obtener el DataOutputStream");
 }
 BufferedReader entradaDesdeServidor = null;
 try {
 entradaDesdeServidor = new BufferedReader(new InputStreamReader(socketCliente.getInputStream()));
 } catch (IOException e1) {
 System.out.println("No se ha podido obtener el BufferedReader");
 }
 try {
 salidaServidor.writeBytes(frase + 'n');
 } catch (IOException e) {
 System.out.println("No se ha podido escribir en cliente");
 }
 try {
 fraseModificada = entradaDesdeServidor.readLine();
 } catch (IOException e) {
 System.out.println("No se ha podido leer la linea");
 }
 System.out.println("DEL SERVIDOR: " + fraseModificada);

InputStream aux = null;
 try {
 aux = socketCliente.getInputStream();
 } catch (IOException e) {
 System.out.println("No se ha podido obtener el InputStream");
 }
 DataInputStream flujo = new DataInputStream(aux);
 try {
 System.out.println(flujo.readUTF());
 } catch (IOException e) {
 System.out.println("Error al obtener datos del servidor");
 }

InputStream aux2 = null;
 try {
 aux2 = socketCliente.getInputStream();
 } catch (IOException e) {
 System.out.println("No se ha podido obtener el InputStream");
 }
 DataInputStream flujo2 = new DataInputStream(aux2);
 try {
 System.out.println(flujo2.readUTF());
 } catch (IOException e) {
 System.out.println("Error al obtener datos del servidor");
 }

try {
 socketCliente.close();
 } catch (IOException e) {
 System.out.println("Error al cerrar el socket");
 }
 }
 }

Copiáis, compiláis y ejecutáis, funcionará perfectamente.

¿Os gusta Java? Próximamente más.


Continúa leyendo
  • darth_Veider

    Muy interesante. Precisamente dentro de poco voy a tener que hacer algo paarecido en clase, asi que me vendrá bien

    Gracias de nuevo.

  • Pingback: La capa de transporte en Internet : TCP a fondo. Volumen IV : Redes Zone : Portal sobre telecomunicaciones y redes()

  • www.redeszone.net

    Taller de practicas cliente y servidor tcp en java.. Great! 🙂

  • www.redeszone.net

    Taller de practicas cliente y servidor tcp en java.. Nifty 🙂

  • emer

    Hola
    quería preguntar si alguien sabe como redirigir la salida de un comando por ejemplo who a la lectura de la consola, está salida debe estar en el servidor y ser mandada al cliente.
    alguna idea?