?? hilocliente.java
字號:
/* * To change this template, choose Tools | Templates * and open the template in the editor. */package controlador;import java.io.*;import java.net.ServerSocket;import java.net.Socket;/** *Clase que gestionara la comunicacion con el cliente remoto. * se implementa como un hilo para recibir las peticiones * sin intervenir en la ejecucion del servidor. * cada vez que el servidor reciba una conexion creara este hilo * para que atienda al cliente conectado. * @author Camilo Andres */public class hiloCliente extends Thread{ /**contante que indica el tama?o del bloque que se va a transmitir cuando se envia un archivo.*/ public static final int TAM_BLOQUE=1024; public static final int PORT_TX=60000; public static final int PORT_RX=50000; private Socket conexionCliente; private servidor miServidor; /**Flujos de entrada y de salida para comunicarse con el * Cliente */ private ObjectOutputStream salidaDatos; private ObjectInputStream entradaDatos; //bandera para controlar la existencia del hilo private boolean finConexion; //------------------------ private ServerSocket txFiles; private ServerSocket rxFiles; //variable estatica que cuenta el numero //de clientes instanciados. public static int numClientes=0; private int puertoTX;//puerto por donde transmite los archivos. private int puertoRX;//puerto por donde recibe un archivo. /** * el constructor recibe el socket y una referencia al servidor. * @param conexionCliente. aqui se crean los flujos de E/S * @param miServidor */ public hiloCliente(Socket conexionCliente,servidor server) throws IOException { super(); this.conexionCliente = conexionCliente; finConexion=false; this. miServidor=server; //se crean los flujos de E/S del socket del cliente conectado //al servidor. se crean de tipo Object para poder enviar y recibir cualquier //tipo de dato. salidaDatos=new ObjectOutputStream(conexionCliente.getOutputStream()); entradaDatos=new ObjectInputStream(conexionCliente.getInputStream()); //envia la lista de archivos para que el cliente la visualice al //conectarse. // enviarListaArchivos(); puertoTX=PORT_TX+numClientes; //serverSocket por donde este cliente crea el socket //para transmitir un archivo. txFiles=new ServerSocket(puertoTX); puertoRX=PORT_RX+numClientes; //serverSocket por donde este cliente crea el socket //para enviar un archivo. rxFiles=new ServerSocket(puertoRX); //cada vez que se instancia un hiloCliente se incrementa el valor de esta variable. numClientes++; }/** * por aqui se recibiran las peticiones del cliente. * ya que no se saben cuando ocurren, es necesario hacerlo en un hilo. */ public void run() { while(finConexion==false) { try { //espera el tipo de mensaje que va a recibir //para saber que debe hacer a continuacion. String tipoMsj = (String) entradaDatos.readObject(); //cuando el clietne quiere descargar un //archivo del servidor if (tipoMsj.equals("BAJAR_ARCHIVO")==true) { //segun el protocolo, despues de enviar el tipo de mjs //debe enviar el nombre del archivo que quiere descargar. String nombreArchivo = (String) entradaDatos.readObject(); //enviarArchivo(nombreArchivo); salidaDatos.writeObject(puertoTX); Socket conTX= txFiles.accept(); hiloTxFileServidor hTx=new hiloTxFileServidor(conTX, nombreArchivo); miServidor.agregarEventoServidor("se descargo el archivo "+nombreArchivo+" desde "+conexionCliente.getInetAddress().getCanonicalHostName()); } //cuando el cliente quiere subir un //archivo al servidor if (tipoMsj.equals("SUBIR_ARCHIVO")==true) { //segun el protocolo, despues de enviar el tipo de mjs //debe enviar el nombre del archivo que quiere subir. String nombreArchivo = (String) entradaDatos.readObject(); //y el puerto por donde debe conectarse el cliente para enviar //el archivo. salidaDatos.writeObject(puertoRX); //despues de enviar el puerto, se espera a que el cliente se conecte Socket conRX= rxFiles.accept(); //creea el hilo que recibe el archivo hiloRxFileServidor hRx=new hiloRxFileServidor(conRX, nombreArchivo); miServidor.agregarEventoServidor("se subio el archivo "+nombreArchivo+" desde "+conexionCliente.getInetAddress().getCanonicalHostName()); } //cuando el clietne quiere ya se quiere desconectar del servodr if (tipoMsj.equals("DESCONECTAR")==true) { finConexion=true;//termina con el hilo. conexionCliente.close();//cierra el socket. rxFiles.close(); txFiles.close(); } //pedir lista de Archivos. if (tipoMsj.equals("LISTA_ARCHIVOS")==true) { //se envia la lista de archivos al cliente. enviarListaArchivos(); //notificacion del evento al servidor. miServidor.agregarEventoServidor(conexionCliente.getInetAddress().getCanonicalHostName()+ " solicitud la actualizacion de la lista"); } } //si hay error de entrada y salida se desconecta la conexion. //y se acaba el hilo. catch (IOException ex) { ex.printStackTrace(); try { //se envia a traves del servidor una notificacion a la interfaz grafica. miServidor.agregarEventoServidor(conexionCliente.getInetAddress().getCanonicalHostName()+ " se desconecto"); //se cierra la conexion del socket. conexionCliente.close(); //se acaba con el hilo. finConexion=true; } catch (IOException ex1) { ex1.printStackTrace(); } } catch (ClassNotFoundException ex) { ex.printStackTrace(); } } } /** * metodo para enviar un mensaje al clietne remoto * @param msj que se va a enviar. de tipo Object para * poder enviar cualquier cosa. */ public void enviarMensajeCliente(Object msj) throws IOException { salidaDatos.writeObject(msj); salidaDatos.flush(); salidaDatos.reset(); } /** * metodo para enviar la lista de archivos presentes en el servidor. * @throws java.io.IOException */ public void enviarListaArchivos() throws IOException { File f=new File("files\\"); //obtiene la lista de archivos presentes en el directorio de archivos. String[] lista=f.list(); //para cumplir el protocolo de la aplicacion envia //la cadena LISTA_ARCHIVOS y luego la lista de archivos. enviarMensajeCliente("LISTA_ARCHIVOS"); enviarMensajeCliente(lista); } /** * metodo que envia un arhivo al cliente. el protocolo de comunicacion * indica que despues de haber hecho la peticion del archivo, se le * envie el tama?o del archivo y el tama?o de los bloque que envia. * @param nombreArchivo * @throws java.io.FileNotFoundException * @throws java.io.IOException */ public void enviarArchivo(String nombreArchivo) throws FileNotFoundException, IOException { //archivo que se va a descargar. File f=new File("src\\files\\"+nombreArchivo); //flujo de entrada de los datos del archivo, se usa para leer el archivo. FileInputStream fin=new FileInputStream(f); long sizeFile=f.length(); //se va a enviar el archivo en bloques de 100 bytes. //se calcula cuantos bloque hay, int numBloques=(int)(sizeFile/TAM_BLOQUE); //los byte que sobren que no alcancen a formar un bloque. int tamResto=(int)(sizeFile%TAM_BLOQUE); //para cumplir el protocolo, el servidor le envia al //cliente la palabra RECIBIR_ARCHIVO luego //el tama?o del archivo y el tama?o del bloque //que va a enviar para que sepa como reconstruir el archivo. //enviarMensajeCliente("RECIBIR_ARCHIVO"); enviarMensajeCliente(sizeFile);//tama?o del archivo enviarMensajeCliente(TAM_BLOQUE);//tama?o del bloques. //lee los numBloques bloques del archivo y los envia. for (int i=0;i<numBloques;i++) { byte datos[]=new byte[TAM_BLOQUE]; //lee el arreglo de TAM_BLOQUE los bytes del arreglo fin.read(datos); //y los envia al cliente que los espera. enviarMensajeCliente(datos); } //hay que enviar el sobrante, leyendolo del archivo byte datos[]=new byte[tamResto]; fin.read(datos); //y enviandolo al clietne. enviarMensajeCliente(datos); fin.close(); }}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -