Come programmare servizi di
rete?
• Programmazione nel modello client
- server usando le Api java: il
package java.net
• Programmazione distribuita con
RMI: il package java.rmi
Modello client - server
• Il server viene programmato per poter fornire
un servizio a chi ne fa richiesta
• Il client inoltra richieste al server e ne elabora
le risposte.
• Si deve adottare un meccanismo che consenta
la comunicazione fra le due entità.
- come indirizzare il messaggio in modo che
arrivi al server destinatario?
- come specificare il processo destinatario del
messaggio?
Architettura di protocolli
I
protocolli
implementano
quelle
funzionalità
che
consentono lo scambio di messaggio sul mezzo fisico
disposto fra due macchine, (ad esempio la suddivisione in
quadri, il rilevamento di errori, il controllo di flusso ecc.)
Server
TCP/UDP
Client
Transport
TCP/UDP
IP
Network
IP
Ethernet Adapter
DataLink
Fisico
Ethernet Adapter
Indirizzamento
• Ogni computer della rete è identificato da un
hostname e da un indirizzo IP unico a 32 bit
es: “www.javasoft.com”  204.160.241.98
• L’indirizzo IP contiene sia l’identificativo della
rete che quello della macchina
• Per verificare l’associazione fra nomi e indirizzi
si puo’ utilizzare il comando nslookup che offre
la lista di tutti i server alias per un indirizzo.
Es. >nslookup www.javasoft.com
Come identificare i processi
• Si assegna ad ogni processo un numero di
porta
• I numeri di porta possono essere
- assegnati in genere a servizi di sistema
(porte da 0-1023)
- dinamici o privati (1024 - 65535)
• I server/daemon usano di solito porte ben
note
- es HTTP = 80 , Telnet = 23, FTP = 21
• I client di solito usano porte dinamiche
• Questa associazione viene usata dai protocolli
di livello transport come TCP o UDP
Concetto di Socket
• Per attivare una connessione fra due processi si
utilizza dunque lo schema Host-Port
– il server è eseguito su un host e aspetta richieste
su una determinata porta
– il client viene eseguito su un host e richiede l’uso di
una porta per effettuare richieste ad un server
• Specificando ora anche il protocollo per la
comunicazione riusciamo a descrivere univocamente
la connessione con una quintupla detta Association:
(protocollo,ind locale, proc locale, ind remoto, proc
remoto)
es: (TCP,123.23.4.221,1500,234.151.124.2,4000)
Concetto di Socket
• La quintupla viene in realtà costituita a partire da due
elementi simmetrici, un’associazione locale ed una
remota:
– Protocollo,
Ind.
locale,
porta
locale
(TCP,123.23.4.221,1500)
– Protocollo,
Ind.
remoto,
porta
remota(TCP
,234.151.124.2,4000)
• Ciascuna si queste parti è detta socket
• Nota: protocolli differente possono usare la stessa
porta;
– 1040 per TCP  1040 UDP
Concetto di Socket
• Un socket è un descrittore di risorsa che
consente ad una applicazione di effettuare
operazioni di lettura / scrittura verso un
particolare dispositivo di I/O.
• Astrazione di un canale di comunicazione tra
processi distribuiti in rete
• Interfaccia per la suite di protocolli TCP/IP
• Punto di arrivo nella comunicazione in rete
Le origini
In un primo tempo nasce in ambiente UNIX
• Negli anni ‘80 la Advanced Research Project
Agency (ARPA ) finanziò l’università di Berkeley per
implementare la suite TCP/IP nel sistema operativo
UNIX
• I ricercatori di Berkeley svilupparono il set
originario di funzioni che fu chiamato interfaccia
socket, creando quindi delle API aggiuntive
• I socket sono stati progettati per supportare vari
protocolli di rete (Unix Domain, Xerox NS Domain)
ma col tempo hanno predominato i protocolli
dell’architettura
Internet
basati
sull’Internet
Protocol(IP): TCP e UDP.
Creazione di un socket
• Lato server
–
–
–
–
–
–
Creazione del socket
Bind ad una porta
Listen, predisposizione a ricevere sulla porta
Accept, blocca il server in attesa di una connesione
Lettura - scrittura dei dati
Chiusura
• Lato client
–
–
–
–
Creazione del socket
Richiesta di connessione
Lettura - scrittura dei dati
Chiusura
Il protocollo TCP
TCP offre un servizio
• che implementa un flusso di byte
• affidabile
• orientato alla connessione
• con ordinamento dei dati
• con controllo di flusso e della congestione
• supporta la demultiplazione fra processi
Esempi di applicazioni : Telnet, Ftp e HTTP
Il protocollo TCP e l’interfaccia
socket
• Nel modello TCP/IP l’interfaccia socket svolge
tutte le operazioni necessarie per stabilire una
connessione:
– si occupa di creare i pacchetti TCP
– stabilisce una connessione con l’algoritmo
del “three way handshake”
– gestisce in generale tutte le problematiche
della trasmissione dei pacchetti
Il protocollo UDP
Realizza solo la distinzione fra i processi che
comunicano fra 2 calcolatori aggiungendo il
concetto di porta ad un indirizzo
• Trasmissione a datagramma : invio si pacchetti
• Non garantisce la consegna
• Non garantisce l’ordinamento
Esempi di applicazioni sono quelle multimediali
Server sequenziali e server
concorrenti
Nel modello client - server si possono distinguere
due diverse implementazioni del server
• Il server comunica con un client per volta (
server iterativo). In questo caso si usa
generalmente il protocollo UDP
• Il server è in grado di soddisfare più richieste
contemporaneamente ( server concorrente ).
In questo caso si usa generalmente il
protocollo TCP.
Server sequenziali e server
concorrenti
• Nel primo caso , se la richiesta del client va a
buon fine il server stabilisce un canale di
comunicazione con il client per trasmettere e
ricevere.
• Nel secondo caso, se la richiesta va a buon
fine, il server prima di creare un canale di
connessione alloca un nuovo socket associato
ad una nuova porta ( tipicamente avvia un
nuovo thread per ogni connessione) a cui cede
la gestione della comunicazione con il client.
In seguito il socket principale si rimette in
ascolto
per
una
nuova
richiesta
di
connessione. Esempi classici di questo tipo
sono i Web server che tipicamente forniscono
il servizio a n browser distinti.
Introduzione ai socket in Java
• L’interfaccia deriva da quella standard di
Berkeley, introdotta nel 1981
• E’ organizzata in maniera da soddisfare i
principi dell’Object Orienting Programming
• Contiene classi per la manipolazione degli
indirizzi e la creazione di socket lato client o
server
• Implementazione nel package java.net
Il package Java.net
Il Java Networking API (java.net) fornisce le classi e
interfacce per
le seguenti funzioni
• Indirizzamento
– InetAddress
• Creazione di connessioni TCP
– ServerSocket,Socket
• Creazione di connessioni UDP
– DatagramPacket,DatagramSocket
• Localizzare risorse di rete
– URL, URLConnection, HttpURLConnection
• Sicurezza ( autenticazione, permessi)
Interfaccia socket
I server e i client si scambiano messaggi attraverso
le Socket API che si collocano immediatamente
sopra al livello transport della comunicazione
Server
Client
TCP/UDP
TCP/UDP
Socket API
IP
IP
Ethernet Adapter
Ethernet Adapter
La classe InetAddress
• Rappresenta un indirizzo IP e fornisce i metodi
per manipolarlo. Non offre costruttori pubblici ma
dei metodi statici per creare istanze di questa
classe:
InetAddress
InetAddress.getByName(String
hostname)
InetAddress[]
InetAddress.getAllByName(String
hostname)
InetAddress InetAddress.getLocalHost()
Una volta istanziato un oggetto di questa classe si
possono utilizzare i metodi
String getHostAddress()
String getHostName()
La classe InetAddress
• Il metodo getByName() può impiegare il DNS per
recuperare l’indirizzo IP associato all’hostname
fornito come argomento
- Si può specificare nel suo argomento sia un
indirizzo IP nella forma decimale che il nome di un
host
- In entrambi i casi, l’oggetto InetAddress
restituito conterrà l’indirizzo IP a 32 bit
• Nel caso che ad un hostname siano associati più
indirizzi IP, li si può ottenere chiamando la
getAllByName
• La getLocalHost restituisce l’indirizzo IP dell’host
su cui viene eseguita
• getHostName e getHostAddress restituiscono
rispettivamente il nome e l’indirizzo IP che
rappresentano
// ESEMPIO DI USO DELLA CLASSE INETADDRESS
import java.net.*;
import java.io.*;
class test_InetAddress{
public static void main(String args[]){
try{
InetAddress ind =
InetAddress.getByName("localhost");
InetAddress indLoc = InetAddress.getLocalHost();
String indirizzo = ind.getHostAddress();
System.out.println("indirizzo host = "+indirizzo);
String nome = ind.getHostName();
System.out.println("nome host = "+nome);
"+indirizzoLoc);
"+nomeLoc);
dell'host");
}}}
String indirizzoLoc = indLoc.getHostAddress();
System.out.println("indirizzo host locale =
String nomeLoc = indLoc.getHostName();
System.out.println("nome host locale =
}catch(UnknownHostException e){
System.out.println("impossibile risalire al nome
Classi per il protocollo TCP
• In Java fornisce due diverse classi per la
comunicazione con il protocollo TCP e che
rispecchiano la struttura client - server:
– creazione socket per il server : classe ServerSocket
– creazione socket per il client : classe Socket
• Ciò è dovuto alle diverse operazioni che
vengono svolte da client e server al momento
di stabilire una connessione : mentre un
server ottiene l’oggetto socket da una
chiamata al metodo accept, il client deve
provvedere a creare un’istanza del socket.
Classe ServerSocket
• Implementa un server socket : viene utilizzata da
server che accettano connessioni dai client.
Costruttori:
ServerSocket()
ServerSocket(int port)
ServerSocket(int port,int backlog)
ServerSocket(int port, int backlog, InetAddress
bindAdd)
• Il parametro port specifica la porta su cui rimanere
in attesa, il parametro backlog il numero massimo
di richieste di connessione (default 50 ) mentre il
parametro bindAdd viene utilizzato dai server
multihomed per specificare un determinato
indirizzo
Classe ServerSocket
• Non è necessario specificare la famiglia dei
protocolli; si opera sempre con IP
• L’impiego di questa classe implica l’uso del
protocollo TCP
• Un eventuale errore genera una eccezione
IOException sollevata dai costruttori
• Il costruttore realizza tutte le operazioni di
socket(), bind() e listen()
Classe ServerSocket
• Il metodo più importante è accept, che
blocca il server in attesa di una connessione.
E’ questo il metodo che restituisce un oggetto
di tipo socket (con le stesse proprietà di quello
originale ) completamente istanziato nei
parametri ( dati locali e remoti) che viene poi
utilizzato per gestire la comunicazione con il
client.
Socket newconnection =
myServerSocket.accept();
• Genera in caso di errore un’eccezione
IOException
• Solo dopo che il metodo accept() ritorna un
socket valido è possibile eseguire operazioni di
I/O su quel socket
Classe ServerSocket
• Sono disponibili anche altri metodi che
permettono di gestire altri aspetti legati ai
socket, come ad esempio timeout o buffer
• setSoTimeout(int timeout):fissa il tempo
massima di attesa per una accept
• setReceiveBufferSize(int size): permette di
settare la dimensione del buffer di ricezione
associato al socket
Classe Socket
• Rappresenta una socket client ed è quindi un
estremo
della
comunicazione
fra
due
macchine. Costruttori:
Public Socket(String host, int Port)
Public Socket(InetAddress, int Port)
• Questi costruttori specificano nel primo
argomento l’host remoto e nel secondo la
porta del server con cui effettuare la
connessione. Altri costruttori permettono di
creare il socket associandolo ad una
determinata porta e indirizzo locale
Classe Socket
• Non è necessario specificare la famiglia dei
protocolli;si opera sempre con IP
• L’impiego di questa classe implica l’uso del
protocollo TCP
• Puo’ generare le eccezioni
- IOException - errore creato alla creazione del
socket
- UnknownHostException - l’host non è stato
trovato
• realizza le operazioni creazione socket ,
connect
Classe Socket
Questa classe fornisce alcuni metodi per poter
estrarre e
manipolare informazioni sul socket creato:
• getLocalAddress,
getInetAddress,
getPort,
getLocalPort forniscono gli indirizzi e le porte di
accesso della connessione
• setTcpNoDelay forza la spedizione dei dati senza
che il pacchetto TCP sia completo
• sendUrgentData spedisce un byte di dati urgenti
sul socket scavalcando altre operazioni di write in
sospeso
• setSoTimeout specifica il tempo di attesa in lettura
sul socket
• setSendBufferSize,
setReceiveBufferSize
specificano le dimensioni dei buffer di lettura e
scrittura
Classe Socket
Metodi per Input/Output dei dati
•InputStream getInputStream() restituisce
uno stream in lettura per il socket
•OutputStream
getOutputStream()
restituisce uno stream in scrittura per il socket
In seguito la lettura/scrittura sui socket viene
eseguita con le
corrispondenti operazioni che si utilizzano per i
file
ServerSocket e Socket:gestione
degli errori
• E’ importante che i socket siano propriamente
chiusi al termine da una applicazione mediante
il metodo close() delle classi ( sia Socket che
ServerSocket) poiché questi sono una risorsa
di rete del sistema
• La chiusura dei socket deve essere eseguita
indipendentemente dal flusso di esecuzione
del programma, utilizzando per questo le
sezioni try e finally
// ESEMPIO DI SERVER ITERATIVO - 1
import java.io.*;
import java.net.*;
public class serverIterativo{
public static void main(String[] args) throws Exception{
StringBuffer revline;
int len;
String line;
ServerSocket listen_socket = new ServerSocket(6789);
System.out.println("in attesa sulla porta 6789");
while(true){
// accetta richieste, le elabora e risponde
}
}
}
// SERVER ITERATIVO - 2 - NEL CICLO WHILE
while(true){
Socket conn = listen_socket.accept();
System.out.println("Ricevuta richiesta di servizio");
// preparazione degli stream di input e output
InputStream sin = conn.getInputStream();
BufferedReader in = new BufferedReader(new InputStreamReader(sin));
PrintStream out = new PrintStream(conn.getOutputStream());
line = in.readLine();
if(line == null) {System.out.println("Ricevuta linee vuota");}
else{
//...la rovescia...
len = line.length();
revline = new StringBuffer(len);
for(int i = len-1; i>=0;i--)
revline.insert(len-1-i,line.charAt(i));
//...e scrive la linea rovesciata
out.println(revline);
System.out.println("Inviata risposta");
}
conn.close();
}
//CLIENT - 1
import java.io.*;
import java.net.*;
public class client{
public static final int DEFAULT_PORT = 6789;
public static void usage(){
System.out.println("Usage: java client <hostname>
[<port>]");
System.exit(0);
}
public static void main(String args[]){
int port = DEFAULT_PORT;
Socket s = null;
if((args.length != 1 ) && (args.length != 2 )) usage();
if(args.length == 1 ) port = DEFAULT_PORT;
else {
try {port = Integer.parseInt(args[1]);}
catch (NumberFormatException e) {usage();}
}
try{//
ESEGUE RICHIESTE E LE ELABORA}
}
}
finally{ try{if(s!= null) s.close();}
catch(IOException e2){}
}
//CLIENT – 2 CODICE CHE ESEGUE LE RICHIESTE E LE ELABORA
try{
s = new Socket(args[0],port);
InputStream sin = s.getInputStream();
BufferedReader fromServer = new BufferedReader(new InputStreamReader(sin));
OutputStream sout = s.getOutputStream();
PrintWriter toServer = new PrintWriter(new OutputStreamWriter(sout));
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Connected to " + s.getInetAddress() + ":"+s.getPort());
String line;
while(true){
System.out.print(">");
line = null;
line = in.readLine();
}
if(line.equals(""))break;
toServer.println(line);
toServer.flush();
line = fromServer.readLine();
if(line == null){
System.out.println("Connection closed by server");
break;
}
System.out.println(line);
}
catch (IOException e){System.err.println(e);}
//ESEMPIO DI SERVER CONCORRENTE - 1
import java.io.*;
import java.net.*;
public class server extends Thread {
public final static int DEFAULT_PORT = 6789;
protected int port;
protected ServerSocket listen_socket;
//Crea un ServerSocket che attende la connessione; inizia il
thread
public server(int port) {
if (port == 0) port = DEFAULT_PORT;
this.port = port;
try {listen_socket = new ServerSocket(port);}
catch (IOException e) {fail(e, "Ex creating server socket");}
System.out.println("Server: listening on port" + port);
this.start();
}
//Body del thread del server. Aspetta ed accetta connessioni da
//client. Per ogni connessione, crea un oggetto Connection per
//gestire la comunicazione attraverso il nuovo socket.
public void run(){
try {
while(true) {
Socket client_socket = listen_socket.accept();
Connection c = new Connection(client_socket);
}
}
catch(Throwable t){};
}
//Fa partire il server, in attesa su una porta opzionalmente
specificata
public static void main(String[] args) {
int port = 0;
if (args.length == 1) {
try {port = Integer.parseInt(args[0]);}
catch (NumberFormatException e) {port = 0;}
}
new server(port);
}} // fine classe server
//La classe seguente e' il thread che gestisce tutta la
comunicazione col //client
class Connection extends Thread {
protected Socket client;
protected BufferedReader in;
protected InputStream sin; protected PrintStream out;
}
//Inizializza gli stream e avvia il thread
public Connection(Socket client_socket) {
client = client_socket;
try {
sin = client.getInputStream();
in = new BufferedReader(new InputStreamReader(sin));
out = new PrintStream(client.getOutputStream());
}
catch (IOException e) {
try {client.close();}
catch (IOException e2){};
System.err.println("Ex. while getting socket streams:" + e);
return;
}
this.start();
}
// metodo run()
//ESEMPIO DI SERVER CONCORRENTE - 3
//Fornisce il servizio
//Legge una linea, la rovescia e la rimanda indietro
public void run() {
String line;
StringBuffer revline;
int len;
try {
for(;;) {
//Legge una linea...
line = in.readLine();
if(line == null) break;
//...la rovescia...
len = line.length();
revline = new StringBuffer(len);
for(int i = len-1; i>=0;i--)
revline.insert(len-1-i,line.charAt(i));
//...e scrive la linea rovesciata
out.println(revline);
}
}
catch (IOException e){}
finally {try {client.close();}
catch (IOException e2){};}
}
Classi per il protocollo UDP
• Questo protocollo basa la comunicazione sullo
scambio di messaggi, che vengono inviati
singolarmente da un computer all’altro.
• I messaggi consistono in array di byte che
vengono inviati al mittente
• I messaggi contengono tutte le informazioni
necessarie per essere recapitati
• I
messaggi
sono
inviati
uno
indipendentemente dall’altro
Le classi che gestiscono questo tipo di
comunicazione iniziano per Datagram
Classe DatagramPacket
• Questa classe serve per preparare il nuovo
pacchetto da spedire attraverso la rete con la
classe DatagramSocket. Costruttori:
public DatagramPacket(byte[] buf, int length);
public DatagramPacket(byte[] buf, int offset,int
length);
public DatagramPacket(byte[] buf, int
offset,InetAddress address,int port);
• Il pacchetto consiste di un semplice array di byte,
alcuni costruttori permettono di specificare la
destinazione
Classe DatagramPacket
• Non è necessario specificare la famiglia dei
protocolli;si opera sempre con IP
• L’impiego di questa classe implica l’uso del
protocollo UDP
• Puo’ generare le eccezioni
- IOException - errore creato alla creazione del
socket
- UnknownHostException - l’host non è stato
trovato
Classe DatagramPacket
• Sono forniti anche altri metodi per gestire i
pacchetti creati:
setAddress,setPort,setData,
setSocketAddress
• permettono di specificare la porta e l’indirizzo
a cui spedire il pacchetto, oltre che specificare
i dati da spedire
Classe DatagramSocket
• Serve per aprire un socket con il quale inviare e
ricevere un DatagramPacket utilizzando il protocollo
UDP. Se il socket è usato solo per inviare non è
necessario specificare la porta, metre se si vuole
anche ricevere si deve specificare la porta a cui il
Datagram è associato.Costruttori:
public DatagramSocket();
public DatagramSocket(int port);
public DatagramSocket(int port, InetAddress
addr);
Si puo’ specificare la porta e l’indirizzo locali su cui si
vuol ricevere
Classe DatagramSocket
• Non è necessario specificare la famiglia dei
protocolli;si opera sempre con IP
• L’impiego di questa classe implica l’uso del
protocollo UDP
- non stabilisce nessuna connessione fra client
e server
- non garantisce né l’ordinamento né l’arrivo
dei pacchetti
• L’overhead basso permette una trasmissione
molto veloce
• Puo’ generare le eccezioni
- IOException - errore creato alla creazione del
socket
- UnknownHostException - l’host non è stato
trovato
Classe DatagramSocket
• send( DatagramPacket p) spedisce un
pacchetto sul socket, includendo tutte le
informazioni necessarie per l’invio
• receive(DatagramPacket p) riceve un
pacchetto sul socket. Il pacchetto ricevuto contiene
indirizzo e porta della macchina che lo ha inviato.
Blocca il thread fino alla ricezione di un pacchetto.
Se il messaggio è più lungo della lunghezza del
pacchetto, il messaggio viene troncato
• getLocalAddress(), getLocalPort()….
• setSoTimeout(),setSendBufferSize,
setReceiveBufferSize()...
Classe DatagramSocket
• Poiché questo tipo di connessione è a scambio di
pacchetti, non si hanno metodi per creazione di
stream, ma solo per impostare o estrarre i
contenuti dei pacchetti
• uso i costruttori per inserire i dati nei pacchetti,
uso il metodo getData() per estrarre i dati dai
pacchetti
• i dati sono sempre contenuti in array di byte, si
effettuano delle operazioni di casting per ottenere
dati tipo Stringa, interi ecc. a partire dagli array.
String messaggio;
byte[] msg = p.getData();
messaggio = new String(msg);
//ESEMPIO DATAGRAM SERVER
import java.net.*;
import java.io.*;
class test_ServerDG{
public static void main(String args[]){
try{
String messaggio;
DatagramSocket srv = new DatagramSocket(8828);
DatagramPacket p = new DatagramPacket(new byte[100],100);
System.out.println("pronto per ricevere sulla porta 8828");
while(true){
srv.receive(p);
byte[] msg = p.getData();
messaggio = new String(msg);
System.out.println(messaggio);
}
}catch(SocketException e){}
catch(IOException e){}
System.out.println("ricevuto un pacchetto");
}
}
//ESEMPIO DATAGRAM CLIENT
import java.net.*;
import java.io.*;
class test_ClientDG{
public static void main(String args[]){
try{
InetAddress dest = InetAddress.getByName("localhost");
String msg="ciao server";
byte[] data =msg.getBytes();
int port=8828;
DatagramPacket p = new
DatagramPacket(data,data.length,dest,port);
DatagramSocket s = new DatagramSocket();
s.send(p);
}catch(SocketException e){}
catch(IOException e){}
System.out.println("spedito un pacchetto sulla porta 8828");
}
}
Comunicazione Multicast
• Il multicast permette di spedire un messaggio ad
un gruppo di processi che vengono identificati da
un indirizzo comune.
• Il multicasting è fatto utilizzando il protocollo UDP
che consente di spedire pacchetti verso indirizzi di
multicast: tutti i client che sono in ascolto su tale
indirizzo riceveranno il pacchetto
• Java implementa il multicast Ip con la classe
java.net.MulticastSocket che è un’estensione
della classe DatagramSocket aggiungendo i metodi
joinGroup() e leaveGroup()
Classe MulticastSocket
• L’indirizzo IP specificato deve essere un indirizzo di
multicast vadido compreso fra 224.0.0.1 e
239.255.255.255
• L’associazione ad un gruppo è obbligatoria solo
per le operazione di ricezione e non per quelle di
spedizione
• Il funzionamento è molto simile a quello della
classe DatagramPacket, si hanno le solite funzioni
send e receive più una estensione della send:
send(DatagramPacket p, byte ttl)
• è disponibile una funzione per il regolare il Time
ToLive:
setTimeToLive(int ttl), getTimeToLive()
Classe URL
• La classe URL rappresenta una Uniform Resource
Locator, un puntatore ad una risorsa nel WWW.
Una risorsa puo’ essere un file, una directory, o un
oggetto di rete generico.
Http://java.sun.com/index.html
• I protocolli possono essere vari, ma i più utilizzati
sono http e ftp. La specifica del protocollo è
necessaria
• Costruttori
URL(String URL)
URL(String protocollo, String host, String port,
String file)
Classe URL
L’accesso ai dati riferiti dall’URL è possibile in3 modi:
• URLConnection openConnection() ritorna un
oggetto URLConnection che rappresenta la
connessione con l’oggetto remoto rappresentato
dall’URL. Nel caso esistano delle sottoclassi
specializzate di URLConnection, la connessione
ritornata
sara’
di
questo
tipo
(es.
HttpURLConnection)
• InputStream
openStream()
apre
una
connessione e ritorna un InputStream per la
lettura da questa connessione. In pratica esegue:
(openConnection()).getInputStream
• getContent() restituisce il contenuto dell’URL
• altri metodi permettono si regolare i parametri di
questa classe:set(...), getHost(), getPort()...
Classe HttpURLConnection
• Rappresenta una connessione ad un URL con
supporto del protocollo HTTP
• Varie istanze di questa classe sullo stesso server
possono condividere una stessa connessione di
rete. In questo caso la chiusura di un InputStream
o OutputStream rilascia le risorse relative
all’istanza associata, ma non ha effetto su altre
connessioni persistenti.
• Definisce una serie di constanti per rappresentare
gli status code ritornati dal server, es.
HTTP_OK=200;HTTP_NON_FOUND=404;
HTTP_INTERNAL_ERROR=500
Classe HttpURLConnection
• Si puo’ gestire la connessione Http tramite alcuni
metodi
• setRequestMethod() specifica il tipo di richiesta
da eseguire
• il contenuto della richiesta è inviato attraverso un
OutputStream
• getResponseCode() resituisce il codice della
risposta del server
• getResponseMessage() restituisce il messaggio
di risposta del server
• è possibilie gestire automaticamente la redirezione
delle richieste con setFollowRedirects()…
import java.io.*;
import java.net.*;
public class test_HttpURLConnection {
public static void main(String[] argv) throws Exception {
URL url = new URL("http://www.html.it/index.asp");
HttpURLConnection connection =
(HttpURLConnection)url.openConnection();
connection.setRequestMethod("GET");
connection.setDoOutput(true);
PrintWriter out = new
PrintWriter(connection.getOutputStream());
out.close();
BufferedReader in = new BufferedReader(new
InputStreamReader(connection.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
in.close();
}
}
import java.net.*;
import java.io.*;
public class getPage{
public static void main(String[] args)
{
String un;
try{
un=args[0];
}catch(ArrayIndexOutOfBoundsException e){
un="http://www.html.it/index.asp";
System.out.println("Nessun URL def., richiedo "+un);
}
System.out.println("URL:"+un);
URL url; boolean tmp=false;
try{
url=new URL(un);
}catch(MalformedURLException e){
System.out.println(”Prendo
http://www.html.it/index.asp");
url=null;
tmp=true;
}
if(tmp)try{
url = new URL("http://www.html.it/index.asp");
}catch(MalformedURLException e){};
BufferedReader stream;
try{
stream =new BufferedReader(new
InputStreamReader(url.openStream()));
}catch(IOException e){
System.out.println("errore di apertura nel file");
stream = null;
System.exit(0);
}
File out = new File("./"+url.getFile());
FileWriter Output;
try{
Output=new FileWriter(out);
}catch(IOException e){
Output=null;
}
String l;
try{
while((l=stream.readLine())!=null){
Output.write(l);
}
Output.flush();
Output.close();
}catch(IOException e){
System.out.println("Errore in lettura");
}
}
}