Ejemplos java y C/linux

Tutoriales

Enlaces

Licencia

Creative Commons License
Esta obra está bajo una licencia de Creative Commons.
Para reconocer la autoría debes poner el enlace http://www.chuidiang.com

Pasar un fichero por socket en java

En este ejemplo vamos a abrir un servidor y un cliente. El cliente le pedirá al servidor un fichero por su nombre, y este se lo enviará. No voy a entrar en detalles de cómo se abren los sockets en java. Como tampoco quiero liar el código, el cliente pedirá un fichero fijo, siempre el mismo, que sabemos que existe y el servidor se lo enviará. La idea es, por tanto, ver cómo enviamos un fichero por un socket, sin liar la forma de pedir el fichero, ni hacer hilos para atender muchos clientes y muchas peticiones ni nada de eso. Solo leer el fichero y enviarlo por el socket.

Definimos la mensajeria

Una vez arrancados el cliente y el servidor, la mensajería entre ellos puede ser parecido a lo siguiente: El cliente le pide un fichero al servidor por medio de un MensajeDameFichero que contenga el nombre del fichero que quiere. El Servidor le contestará con uno o más mensajes MensajeTomaFichero. Este mensaje contendrá básicamente un array de bytes con el contenido del fichero, más otros campos que detallaremos luego.

¿Por qué uno o varios MensajeTomaFichero?. Se puede hacer perfectamente con un sólo mensaje. Se lee TODO el fichero, se mete en el array de bytes del mensaje y se envía. Esto no parece que sea muy adecuado si el fichero es grande. Es mejor definir un tamaño suficientemente grande, como 4000 bytes o así) y enviar el fichero en trozos. En el ejemplo y para poder probar cómodamente, he puesto 10 bytes como tamaño máximo, pero este valor no es eficiente, ya que manda muchos mensajes para un fichero pequeño. Puedes cambiar fácilmente el valor en el ejemplo.

Necesitamos entonces, dos mensajes. Un MensajeDameFichero del cliente al servidor y otro MensajeTomaFichero del servidor al cliente. Aprovechando las características de java, usamos dos clases con estos nombres que implementen la interface Serializable. De esta forma se puede enviar de forma muy sencilla el mensaje, pero perdemos compatibilidad con otros lenguajes, como C++. Haciéndolo así, no podemos programar por ejemplo, el servidor en java y el cliente en C++. Si quieres usar distintos lenguajes, échale un ojo a este tutorial.

El MensajeDameFichero únicamente necesita un atributo String con el nombre del fichero.

El MensajeTomaFichero necesita más cosas:

Aquí tienes ambas clases:

MensajeDameFichero.java
public class MensajeDameFichero implements Serializable
{
    /** path completo del fichero que se pide */
    public String nombreFichero;
}

MensajeTomaFichero.java
public class MensajeTomaFichero implements Serializable
{
    /** Nombre del fichero que se transmite. Por defecto "" */
    public String nombreFichero="";

    /** Si este es el último mensaje del fichero en cuestión o hay más después */
    public boolean ultimoMensaje=true;

    /** Cuantos bytes son válidos en el array de bytes */
    public int bytesValidos=0;

    /** Array con bytes leidos del fichero */
    public byte[] contenidoFichero = new byte[LONGITUD_MAXIMA];
   
    /** Número máximo de bytes que se enviaán en cada mensaje */
    public final static int LONGITUD_MAXIMA=10;
}

El servidor

Vamos con el código del servidor. Los pasos que va a dar son los siguitentes:

El cliente

En la parte del cliente, simplemente se abre el socket, se pide el mensaje y se escribe en un fichero todo lo que venga.

El ejemplo completo

Esto es todo. En fuentes.zip tienes los fuentes completos. Solo tienes que desempaquetarlos, compilarlos y ejecutar los main() de las clases ServidorFichero para el servidor y ClienteFichero para el cliente. Si no tocas las fuentes, transmitirán un fichero "d:\hola.txt", El cliente lo recibirá y lo guardará en "d:\hola.txt_copia". Puedes cambiarlo para que sea el  fichero que quieras. Si vas a hacerlo con un fichero binario, quita del ClienteFichero.java las líneas que sacan el fichero por pantalla.

Estadísticas y comentarios

Numero de visitas desde el 4 Feb 2007: