No es un bug, es una característica no documentada

sábado, 30 de enero de 2016

Procesos y servicios. Programación de sockets (III)

Puedes leer las dos entradas anteriores pulsando en (I) o (II)

ObjectInputStream & ObjectOutputStream

Las clases ObjectInputStream y ObjectOutputStream nos permiten enviar objetos a través de sockets TCP.

ObjectOutputStream outObjeto = new ObjectOutputStream(socket.getOutoutStream());
ObjectInputStream inObjeto = new ObjectInputStream(socket.getInputStream());

Utilizaremos los métodos readObject() para leer el objeto del stream y writeObject() para escribir el objeto al stream.

Serialización

Para que un programa java pueda convertir un objeto en un montón de bytes y pueda luego recuperarlo, el objeto necesita ser Serializable. Al poder convertir el objeto a bytes, ese objeto se puede enviar a través de red, guardarlo en un fichero, y después reconstruirlo al otro lado de la red, leerlo del fichero…

Para que un objeto sea serializable basta con que implemente la interfaz Serialzable. Como la interfaz Serializable no tiene métodos, es muy sencillo implementarla, basta con un implements Serializable y nada más.

Si dentro de la clase hay atributos que son otras clases, éstos a su vez también deben ser Serializables. Con los tipos de java (String, Integer, etc.) no hay problema porque lo son. Si ponemos como atributo nuestras propias clases, éstas a su vez deben implementar Serializable.

Ejemplo

En el siguiente ejemplo vamos a ver como el programa servidor crea un objeto Persona, dándole valores y se lo envía al programa cliente, el programa cliente realiza los cambios oportunos en el objeto y se lo devuelve modificado al servidor.

ARCHIVO SERVIDOROBJETO.JAVA

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

public class ServidorObjeto {
     
      public static void main(String[] arg) throws IOException, ClassNotFoundException {
           
            int numeroPuerto = 6000;// Puerto
            ServerSocket servidor = new ServerSocket(numeroPuerto);
            System.out.println("Esperando al cliente.....");
            Socket cliente = servidor.accept();
           
            // Se prepara un flujo de salida para objetos
            ObjectOutputStream outObjeto = new ObjectOutputStream( cliente.getOutputStream());
           
            // Se prepara un objeto y se envía
            Persona per = new Persona("Juan", 20);
            outObjeto.writeObject(per);
           
            //enviando objeto
            System.out.println("Envio: " + per.getNombre() +"*"+ per.getEdad());
           
            // Se obtiene un stream para leer objetos
            ObjectInputStream inObjeto = new ObjectInputStream( cliente.getInputStream());
            Persona dato = (Persona) inObjeto.readObject();
            System.out.println("Recibo: " + dato.getNombre() + "*" + dato.getEdad());
           
            // CERRAR STREAMS Y SOCKETS
            outObjeto.close();
            inObjeto.close();
            cliente.close();   
            servidor.close();
           
      }// Fin de main
     
}// Fin de ServidorObjeto

ARCHIVO CLIENTEOBJETO.JAVA

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

public class ClienteObjeto {
     
      public static void main(String[] arg) throws IOException, ClassNotFoundException {
           
            String Host = "localhost";
            int Puerto = 6000;//puerto remoto
            System.out.println("PROGRAMA CLIENTE INICIADO....");
            Socket cliente = new Socket(Host, Puerto);
                 
            //Flujo de entrada para objetos
            ObjectInputStream perEnt = new ObjectInputStream(cliente.getInputStream());
           
            //Se recibe un objeto
            Persona dato = (Persona) perEnt.readObject();
           
            //recibo objeto
            System.out.println("Recibo: " + dato.getNombre() + "*" + dato.getEdad());
           
            //Modifico el objeto
            dato.setNombre("Juan Ramos");
            dato.setEdad(22);
           
            //FLUJO DE salida para objetos
            ObjectOutputStream perSal = new ObjectOutputStream( cliente.getOutputStream());
           
            // Se envía el objeto
            perSal.writeObject(dato);
            System.out.println("Envio: " + dato.getNombre() + "*" + dato.getEdad());
           
            // CERRAR STREAMS Y SOCKETS
            perEnt.close();
            perSal.close();
            cliente.close();
           
      }// Fin de main
     
}// Fin de ClienteObjeto

ARCHIVO PERSONA.JAVA

import java.io.Serializable;

@SuppressWarnings("serial")
public class Persona implements Serializable {
     
      String nombre;
      int edad;
     
      public Persona(String nombre, int edad) {
            super();
            this.nombre = nombre;
            this.edad = edad;
      }
      public Persona() { super(); }
     
      public String getNombre() {  return nombre; }
      public void setNombre(String nombre) { this.nombre = nombre; }
      public int getEdad() { return edad; }
      public void setEdad(int edad) {this.edad = edad; }

}// Fin de Persona

Envío de objetos a través de Sockets UDP

Utilizaremos las clases ByteArrayOutputStream y ByteARrayInputStream. Se necesita convertir el objeto a un array de bytes.

Persona persona = new Persona("Maria", 22);

// Convertimos objeto a bytes
ByteArrayOutputStream bs = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(bs);

// Escribir objeto a bytes
out.writeObject(persona);

// Cerrar stream
out.close();

// Objeto en bytes
byte[] bytes = bs.toByteArray();

Para convertir los bytes recibidos por el datagrama en un objeto Persona escribimos:

// Recibo datagrama
byte[] recibidos = new byte[1024];
DatagramPacket paqRecibido = new DatagramPacket(recibidos, recibidos.length);
socket.receive(paqRecibido); // recibo el datagrama

// Convertirmos bytes a objetos
ByteArrayInputStream bais = new ByteArrayInputStream(recibidos);
ObjectInputStream in = new ObjectInputStream(bais);

// Obtengo objeto
Persona persona = (Persona)in.readObject();


in.close(); // Cerrar stream

0 comentarios:

Publicar un comentario