FTP (File Transfer Protocol) es un protocolo de transferencia de ficheros entre un cliente y un servidor. Básicamente se utilizar para subir/bajar ficheros a/desde un sitio remoto. Sus características principales son las siguientes:
A continuación se muestran ejemplos de código para implementar un cliente y un servidor FTP, utilizando la librería Apache MINA FtpServer
. . . FTPClient clienteFtp = new FTPClient(); clienteFtp.connect(IP, PUERTO); clienteFtp.login(USUARIO, CONTRASENA); /* * En el modo pasivo es siempre el cliente quien abre las conexiones * Da menos problemas si estamos detras de un firewall, por ejemplo */ clienteFtp.enterLocalPassiveMode(); clienteFtp.setFileType(FTPClient.BINARY_FILE_TYPE); . . .
. . . // Lista los ficheros del servidor (a modo de ejemplo) FTPFile[] ficheros = clienteFtp.listFiles(); for (int i = 0; i < ficheros.length; i++) { System.out.println(ficheros[i].getName()); } // Fija los ficheros remoto y local String ficheroRemoto = "/modelo.txt"; File ficheroLocal = new File("modelo.txt"); System.out.println("Descargando fichero '" + ficheroRemoto + "' del servidor . . ."); // Descarga un fichero del servidor FTP OutputStream os = new BufferedOutputStream(new FileOutputStream(ficheroLocal)); if (clienteFtp.retrieveFile(ficheroRemoto, os)) System.out.println("El fichero se ha recibido correctamente"); os.close(); . . .
. . . FtpServerFactory serverFactory = new FtpServerFactory(); ListenerFactory miListenerFactory = new ListenerFactory(); miListenerFactory.setPort(PUERTO); serverFactory.addListener("default", miListenerFactory.createListener()); try { ConnectionConfigFactory miConnectionConfigFactory = new ConnectionConfigFactory(); miConnectionConfigFactory.setAnonymousLoginEnabled(true); ConnectionConfig connectionConfig = miConnectionConfigFactory.createConnectionConfig(); serverFactory.setConnectionConfig(connectionConfig); // Fija la configuracion de las cuentas de usuario PropertiesUserManagerFactory userManagerFactory = new PropertiesUserManagerFactory(); userManagerFactory.setFile(new File("usuarios.properties")); serverFactory.setUserManager(userManagerFactory.createUserManager()); FtpServer servidorFtp = serverFactory.createServer(); servidorFtp.start(); } catch ( . . . ) { . . . } ...
# Password: "admin" # Username: "admin" ftpserver.user.admin.userpassword=21232F297A57A5A743894A0E4A801FC3 ftpserver.user.admin.homedirectory=./home ftpserver.user.admin.enableflag=true ftpserver.user.admin.writepermission=true ftpserver.user.admin.maxloginnumber=0 ftpserver.user.admin.maxloginperip=0 ftpserver.user.admin.idletime=0 ftpserver.user.admin.uploadrate=0 ftpserver.user.admin.downloadrate=0
HTTP es un protocolo utilizado para la transferencia de hipertexto (páginas web) a través de la red (normalmente Internet). El hipertexto es un sistema de documentos (de texto) en el que éstos no están organizados de forma secuencial sino que es posible acceder a cualquiera de ellos desde cualquier otro, incluso si éstos provienen de diferentes fuentes (sitios web), mediante lo que se conoce como un hipervínculo. Sus características principales son las siguientes:
Para implementar un cliente HTTP basta con fijar una URL a un componente JEditorPane
, puesto que es capaz de renderizar páginas web HTML directamente (aunque se una forma bastante básica).
. . . JEditorPane epPagina = new JEditorPane(); String url = "http://psp.abrilcode.com"; try { epPagina.setPage(url); } catch (IOException ioe) { // Error al intentar cargar la URL } } . . .
En este caso implementamos directamente la versión multihilo del servidor HTTP. Así, de forma similar como hicimos con el servidor echo, en una clase principal esperamos las conexiones de clientes de forma que sean atendidos mediante hilos que serán lanzados por cada una de las conexiones recibidas.
. . . boolean conectado = true; ServerSocket servidor = null; try { servidor = new ServerSocket(80); while (conectado) { ConexionCliente conexionCliente = new ConexionCliente(servidor.accept()); conexionCliente.start(); } if (servidor != null) servidor.close(); } catch ( . . . ) { . . . } . . .
Ya en la clase ConexionCliente
será donde analicemos la petición recibida para comprobar que documento HTML nos ha solicitado el cliente.
. . . @Override public void run() { try { String peticion = entrada.readLine(); if (peticion.startsWith("GET")) { String[] partes = peticion.split(" "); String rutaFichero = partes[1].substring(1); /* Si no ha solicitado ninguna pagina es que ha solicitado la * pagina por defecto que normalmente es index.html */ if (rutaFichero.equals("")) rutaFichero = "index.html"; File fichero = new File("htdocs" + File.separator + rutaFichero); if (!fichero.exists()) { salida.writeBytes("HTTP/1.0 404 Not Found\r\n"); salida.writeBytes("\r\n"); salida.writeBytes("<html><body>Documento no encontrado</body></html >\r\n"); desconectar(); return; } else { . . . } } } } . . .
En el caso de que la petición prospere, habrá que preparar la respuesta, que estará compuesta de cierta información de protocolo más el contenido del documento solicitado.
. . . // Prepara el fichero que se tiene que enviar FileInputStream fis = new FileInputStream(fichero); int tamanoFichero = (int) fichero.length(); byte[] bytes = new byte[tamanoFichero]; fis.read(bytes); fis.close(); // Prepara las cabecera de salida para el navegador salida.writeBytes("HTTP/1.0 200 OK\r\n"); salida.writeBytes("Server: MiJavaHTTPServer\r\n"); if (rutaFichero.endsWith(".jpg")) salida.writeBytes("Content -Type: image/jpg\r\n"); else if (rutaFichero.endsWith(".html")) salida.writeBytes("Content -Type: text/html\r\n"); salida.writeBytes("Content -Length: " + tamanoFichero + "\r\n"); // Linea en blanco, obligatoria segun el protocolo salida.writeBytes("\r\n"); // Envia el contenido del fichero salida.write(bytes, 0, tamanoFichero); desconectar(); . . .
Los proyectos de los ejercicios que se vayan haciendo en clase estarán disponibles en el repositorio psp-ejercicios de BitBucket
© 2024 Santiago Faci y Fernando Valdeón