Diferencia entre revisiones de «Xeración de servizos en rede con Java»

De MediaWiki
Ir a la navegación Ir a la búsqueda
Línea 112: Línea 112:
 
| URI <br> URL
 
| URI <br> URL
 
|-
 
|-
−
! Conexións a URL
+
! Conexións <br> a <br>URL
 
| Para xestionar as conexións a recursos identificados mediante URL
 
| Para xestionar as conexións a recursos identificados mediante URL
 
| URLConnection: conexión a unha URL <br> HttpURLConnecion: subclase de URLConnection que proporciona funcionalidade específica para o protocolo HTTP. Existe tamén unha API para HTTP máis recente implementada no paquete java.net.http
 
| URLConnection: conexión a unha URL <br> HttpURLConnecion: subclase de URLConnection que proporciona funcionalidade específica para o protocolo HTTP. Existe tamén unha API para HTTP máis recente implementada no paquete java.net.http

Revisión del 18:42 13 nov 2021

Introducción

A nivel pedagóxico, estes son os resultados de aprendizaxe e criterios de avaliación:

  • RA2. Desenvolve aplicacións que ofrezan servizos en rede, para o que utiliza librarías de clases e aplica criterios de eficiencia e dispoñibilidade.
  • CA2.1. Analizáronse librarías que permitan implementar protocolos estándar de comunicación en rede.
  • CA2.2. Programáronse clientes de protocolos estándar de comunicacións e verificouse o seu funcionamento.
  • CA2.3. Desenvolvéronse e probáronse servizos de comunicación en rede.
  • CA2.4. Analizáronse os requisitos necesarios para crear servizos capaces de xestionar varios clientes concorrentes.
  • CA2.5. Incorporáronse mecanismos para posibilitar a comunicación simultánea de varios clientes co servizo.
  • CA2.6. Verificouse a dispoñibilidade do servizo.
  • CA2.7. Depuráronse e documentáronse as aplicacións desenvolvidas.

Clases de Java para comunicacións en rede

Na unidade didáctica anterior víronse clases de baixo nivel do paquete java.net da biblioteca estándar de clases de Java coas que se poden desenvolver aplicacións de cliente e de servidor de nivel de aplicación sobre os protocolos de nivel de transporte UDP e TCP.

Pódense utilizar estas clases para desenolver aplicacións de cliente para protocolos estándares de red tales coma FTP, POP3, etc; mais isto require dun conñecemento detallado do protocolo e ocuparse dos detalles do seu funcionamento interno. Para a maioría das aplicacións é suficiente (e resulta máis sinxelo) utilizar API ou bibliotecas de clases específicas para estes protocolos. Así pois veremos as API disponibles para os diferentes protocolos.

Clases de alto nivel del paquete estándar java.net

Ademáis das clases de baixo nivel, o paquete java.net da biblioteca estándar de clases de Java proporciona clases de alto nivel para protocolos estándares de nivel de aplicación.

Estas clases de alto nivel están baseadas na abstracción das URI ou URL, que designan e proporcionan acceso a unha grande variedade de recursos accesibles mediante diversos protocolos, coma por exemplo HTTP e FTP. O concepto de URL resulta familiar para calquiera que navegue por internet. As seguintes URL permiten obter un mesmo ficheiro de dous servidores diferentes e mediante dous protocolos diferentes (HTTP e FTP); basta con introducilas na barra de enderezos dun navegador web para iniciar a súa descarga:

NOTA. Nas últimas versións dos navegadores xa non é posible acceder mediante o protocolo FTP, por considerarse un protocolo inseguro. De momento aínda permiten o seu uso facendo cambios na configuración por defecto, pero é posible que en pouco tempo xa non sexa posible acceder a sitios FTP mediante o protocolo FTP dende o navegador. A solución pasará por usar un cliente FTP... ou utilizar protocolos máis seguros para a transferencia de ficheiros, coma pode ser scp.

Os recursos son secuencias de bytes e as clases da biblioteca estándar de clases de Java permiten designalos mediante unha URL. As clases de alto nivel de java.net permiten obter un InputStream para ler os contidos dun recurso designado mediante unha URL. Estas clases proporcionan un acceso sinxelo ós recursos de xeito uniforme e independente do protocolo.

Con todo, a funcionalidade destes protocolos vai máis alá do que ofrecen estas clases; para algunhas aplicacións pode ser necesario utilizar funcionalidades adicionais destes protocolos, e existen clases que o permiten.

Apache Commons Net

A biblioteca de clases Apache Commons Net inclúe clases de alto nivel clientes dos protocolos de rede estándares máis importantes.

A biblioteca de clases, a documentación y o código fonte están disponibles no ficheiro

commons-net-x.y-bin.tar.gz
x.y é a versión 

Este ficheiro comprimido contén varios ficheiros jar que a súa vez conteñen a biblioteca de clases, e os seus javadocs nun directorio api-docs (tamén accesibles na web). É relevante salientar entre as bibliotecas (libraries):

  • commons-net-x.y.jar
  • commons-net-examples-x.y.jar, con clases auxiliares útiles para algunhas aplicacións

Principales clases clientes de protocolos de Apache Commons Net

A xerarquía para as principais clases de Apache Commons Net clientes de protocolos son:

SocketClient
 +----- TelnetClient
 +----- FTP
 +        \----- FTPClient
 +                 \----- FTPSClient
 +----- TFTP
 +        \----- TFTPClient
 +----- POP3
 +        \----- POP3Client
 +                 \----- POP3SClient
 +----- SMTP
 +        \----- SMTPClient
 +                 \----- SMTPSClient
 +                          \----- AuthenticatingSMTPClient 
 +----- IMAP
 +        \----- IMAPClient
 +                 \----- IMAPSClient
 +                          \----- AuthenticatingIMAPClient
 +----- DaytimeTCPClient
 \----- TimeTCPClient
DatagramSocketClient
 +----- NTPUDPClient
 +----- DayTimeUDPClient
 \----- TimeUDPClient

En grosa están as clases clientes, que segue as seguintes regras xerais no referente á súa nomenclatura:

  • As clases que teñen o nombre dun protocolo (por exemplo, IMAP) teñen diversos métodos que corresponden a comandos do protocolo. Pódense utilizar para desenvolver aplicacións que interactúan co protocolo a baixo nivel, enviando comandos.
  • As clases fillas das anteriores, que teñen por nome o nome dun protocolo máis Client (por exemplo, POP3Client), son clases clientes do protocolo. Teñen métodos que permiten utilizar o protocolo a máis alto nivel.
  • As clases fillas das anteriores, que teñen o nome do protocolo + S + Client (por exemplo FTPSClient) son clases clientes do protocolo sobre unha capa de seguridade baseada en TLS/SSL.
  • As clases fillas das anteriores que comezan por Authenticating (por exemplo AuthenticatingIMAPClient ) teñen métodos que permiten a autenticación de clientes cos mecanismos que o protocolo correspondente proporciona para iso.

As clases Client de Apache Commons Net teñen métodos:

  • connect para a conexión cun servidor
  • login para o inicio dunha sesión co servidor
  • logout para terminar a sesión
  • disconnect para pechar a conexión

Outras bibliotecas de clases

O relevante protocolo SSH non conta con soporte das anteriores clases. A biblioteca de clases JSCH proporciona clases que se poden utilizar para desenvolver aplicacións clientes deste protocolo.

Comparativa de APIs

Resumidamente, para dar unha resposta sinxela á necesidade de uso dos protocolos estándares de rede máis habituales, cabe considerar as seguientes API.

APIs con clases clientes para diferentes protocolos estándares
API Protocolos
java.net HTTP HTTPS FTP FTPS
Apache Commons Net TELNET FTP FTPS POP3 POP3S SMTP SMTPS IMAP IMAPS NTP
JSCH SSH FTPS

Clases estándares de Java para URL

Pódese interaccionar con recursos identificados mediante unha URL coas clases estándares de Java dentro do paquete java.net

Clases de Java para URL
Significado Clases
URI, URL Identificación e localizadores URI
URL
Conexións
a
URL
Para xestionar as conexións a recursos identificados mediante URL URLConnection: conexión a unha URL
HttpURLConnecion: subclase de URLConnection que proporciona funcionalidade específica para o protocolo HTTP. Existe tamén unha API para HTTP máis recente implementada no paquete java.net.http


Métodos da clase URL
Método Funcionalidade
URL (String spec) Construtor para un URL a partir da súa especificación en forma de String
URL (String protocol, String host, String file)
URL (String protocol, String host, int port String file)
Construtor para un URL a partir dos componentes. Protocolo corresponde ó esquema ou scheme. File corresponde á ruta ou path
String getProtocol()
String getUserInfo()
String getHost()
int getPort()
int getDefaultPort()
String getAuthority()
String getPath()
String getQuery()
String getFile()
Métodos getter para diferentes partes dunha URL. Comentar que get getFIle() devolve a concatenación de getPath() máis getQuery()
URLConnection openConnection() Devolve un URLConnection que se pode utilizar para obter os contidos do recurso especificado polo URL, e tamén para enviar información hacia él
InputStream openStream() Abre unha conexión ó URL e devolve un InputStream que se pode utilizar para obter os seus contidos

Exemplos

Telnet

TelnetClientExample

Exemplo de uso de TelnetClient oficial de Apache Commons Net.

WeatherTelnet

Exemplo de uso trivial da clase TelnetClient.

Conecta ó servidor da Universdade de Michigan no porto 3000 (um-weather.sprl.umich.edu:3000) e permítelle o usuario interactuar co servidor vía entrada por teclado.

Telnet pasando servidor e porto como parámetro

Mesmo exemplo que o anterior, pero adaptado de xeito máis xenérico, permitindo acceder a un servidor (por ip ou nome de dominio) e portos específicados como parámetros de liña de comandos.

Con estes parámetros chámase o constructor da clase TelnetClient,que ten os métodos getOutputStream() e getInputStream() para obter os streams que permiten enviar e recibir información a e desde o socket.

Neste exemplo utilízase a clase auxiliar examples.util.IOUtil para enganchar entrada e saída estándares System.in e System.out a estes streams.

Psando como parámetros rainmaker.wunderground.com e 3000 este programa fai o mesmo que o programa de exemplo anterior.

 1 import java.io.IOException;
 2 import org.apache.commons.net.telnet.TelnetClient;
 3 import org.apache.commons.net.examples.util.IOUtil;
 4 public class ClienteTelnetGenerico {
 5   public static void main(String[] args) {
 6     if(args.length < 2) {
 7       System.out.println(“ERROR: indicar: servidor puerto”);
 8       System.exit(1);
 9     }
10     String servidor = args[0];
11     int puerto = Integer.parseInt(args[1]);
12     
13     TelnetClient telnet = new TelnetClient();
14     try {
15       telnet.connect(servidor, puerto);
16     } catch (IOException e) {
17       e.printStackTrace();
18       System.exit(2);
19     }
20     IOUtil.readWrite(telnet.getInputStream(), telnet.getOutputStream(),
21       System.in, System.out);
22     try {
23       telnet.disconnect();
24     } catch (IOException e) {
25       e.printStackTrace();
26       System.exit(3);
27     }
28   }
29 }

FTP

FTPClientExample

Exemplo de uso que permite súbdas, baixadas,etc. sobre FTP, FTPS e FTP sobre HTTP.

ServerToServerFTP

Exemplo de uso que permite a transferencia dun ficheiro de servidor a servidor (de host1 a host2)

TFTPExample

Exemplo de uso de un cliente tfrp (trivial ftp é un protocolo distinto a ftp)

listaficherosftp

O seguiente programa conéctase a un servidor de FTP e proporciona unha lista dos ficheiros e directorios disponibles.

Pásaselle como parámetro de liña de comandos:

  • un servidor (enderezo ip ou nome de dominio).
  • un usuario e contrasinal (opcional).

Inténtase establecer o modo pasivo con clienteFTP.enterLocalPassiveMode(). O servidor podería non soportar este modo (pouco probable). Establécese o modo binario con clienteFTP.setFileType(FTP.BINARY_FILE_TYPE).

Pódese utilizar este programa para:

  • conectarse a un servidor de FTP público que permita conexión anónima (por ejemplo ftp.rediris.es)
  • para conectar a un servidor privado, cun nome de usuario e contrasinal.

No tocante o tratamento de error, tras calquera erro unha vez establecida a conexión, saese con return; co que se executa o bloque finally que pecha a conexión.

 1 package listaficherosftp;
 2 import java.io.IOException;
 3 import org.apache.commons.net.ftp.FTPClient;
 4 import org.apache.commons.net.ftp.FTPReply;
 5 import org.apache.commons.net.ftp.FTPFile;
 6 import org.apache.commons.net.ftp.FTP;
 7 
 8 public class ListaFicherosFTP {
 9   public static void main(String[] args) {
10     if (args.length < 1) {
11       System.out.println(“ERROR: indicar como parámetros:”);
12        System.out.println(“servidor usuario(opcional) contraseña(opcional)”);
13       System.exit(1);
14     }
15     String servidorFTP = args[0];
16     String usuario = “anonymous”, password = “”;
17     if (args.length >= 2) {
18       usuario = args[1];
19     }
20     if (args.length >= 3) {
21       password = args[2];
22     }
23     FTPClient clienteFTP = new FTPClient();
24     try {
25       clienteFTP.connect(servidorFTP);
26       int codResp = clienteFTP.getReplyCode();
27       if (!FTPReply.isPositiveCompletion(codResp)) {
28          System.out.printf(“ERROR: Conexión rechazada con cód. respuesta %d.\n”,codResp);
29         System.exit(2);
30       }
31       clienteFTP.enterLocalPassiveMode();
32       clienteFTP.setFileType(FTP.BINARY_FILE_TYPE);
33       if (usuario != null && password != null) {
34         boolean loginOK = clienteFTP.login(usuario, password);
35         if (loginOK) {
36           System.out.printf(“INFO: Login con usuario %s realizado.\n”,usuario);
37         }
38         else {
39           System.out.printf(“ERROR: Login con usuario %s rechazado.\n”,usuario);
40           return;
41         }
42       }
43       System.out.printf(
44          “INFO: Conexión establecida, mensaje de bienvenida:\n====\n%s\n====\n”,clienteFTP.getReplyString());      
45       System.out.printf(“INFO: Directorio actual en servidor: %s, contenidos:\n”,clienteFTP.printWorkingDirectory());
46       
47       FTPFile[] fichServ = clienteFTP.listFiles();
48       for(FTPFile f: fichServ) {
49         String infoAdicFich = “”;
50         if(f.getType() == FTPFile.DIRECTORY_TYPE) {
51           infoAdicFich = “/”;
52         }
53         else if(f.getType() == FTPFile.SYMBOLIC_LINK_TYPE) {
54           infoAdicFich = “ -> “ + f.getLink();          
55         }
56         System.out.printf(“%s%s\n”, f.getName(), infoAdicFich);
57       }
58     } catch (IOException e) {
59       System.out.println(“ERROR: conectando al servidor”);
60       e.printStackTrace();
61       return;
62     } finally {
63       if (clienteFTP != null) {
64         try {
65           clienteFTP.disconnect();
66           System.out.println(“INFO: conexión cerrada.”);
67         } catch (IOException e) {
68           System.out.println(“AVISO: no se pudo cerrar la conexión.”);
69         }
70       }
71     }
72   }
73 }

Créditos e referencias

Apache Commons

Tarefas