1
Internet Socket
Programmazione in Rete e Laboratorio
Matteo Baldoni Dipartimento di Informatica Universita` degli Studi di Torino C.so Svizzera, 185 I-10149 Torino baldoni@di.unito.it
http://www.di.unito.it/~baldoni/didattica
2
Architettura Client/Server
Un servizio presso un computer-server è identificato dai seguenti valori:
■ IP (32 bit, presto 64 bit)
■ Port (16 bit)
Alcuni tipici servizi:
■ telnet
■ http
■ ftp
■ SMTP, IMAP4
■ NFS, DNS, NIS, ...
IP Address IP Address
IP Address
IP Address Servizi telnet ftp
http TCP IMAP
TCP
TCP Server
Client
Client
Client
3
Socket
■ È una astrazione software che rappresenta il terminale di una connessione tra due computer
■ Per ogni connessione esiste un socket in ognuno dei computer coinvolti
■ Il client effettua la richiesta di una connessione ad un server per un servizio collegato ad una determinata porta
■ Se la richiesta è accettata la connessione tra i due applicativi dei due computer è stabilita
IP Address
IP Address
Port
Port TPC Server
Client Socket:
<IP Client, Port Client, IP Server, Port Server>
Socket:
<IP Client, Port Client, IP Server, Port Server>
4
Socket e Stream in Java
■ Da ogni socket è possibile ottenere uno stream di input ed uno di output
■ L’uso dei socket è trasparente: readLine e println
BufferedReader in = new BufferedReader(
new InputStreamReader(
socket.getInputStream()));
PrintWriter
out = new PrintWriter(
new BufferedWriter(
new OutputStreamWriter(
socket.getOutputStream())),
true); Abilita il flush immediato
5
Socket in Java
■ Package da importare java.net
■ La classe java.net.Socket implementa un “client socket”
◆ richiede l’indirizzo IP e il numero della porta del servizio a cui vogliamo connetterci
■ La classe java.net.ServerSocket implementa un
“server socket”
◆ richiede il numero della porta a cui vogliamo associare il servizio
◆ crea un “server” che attende le richieste di connessione
◆ restituisce un socket nel momento in cui accetta un collegamento completamente istanziato nei parametri di collegamento (IP e Porta locale e remota).
IP Address
IP Address
Port
Port TPC Server
Client Socket ServerSocket
6
Socket (Client)
■ Crea una connessione con un’applicazione server (in attesa in una accept()) e restituisce il relativo socket
■ Le eccezioni che possono essere sollevate sono del tipo IOException (da catturare e gestire!)
IP Address Port
Client Socket Socket socket = new Socket(IP, PORT);
[…]
socket.close();
E`un valore intero, in genere non inferiore a 1024 (riservati al sistema) e rappresenta il numero della porta a cui Vogliamo connetterci E`un oggetto del tipo java.net.InetAddress contenente l’indirizzo IP della macchina a cui vogliamo connetterci ad esempio speedy/130.192.241.1
2
7
Un esempio: connessione alla porta 80!
■ Le prime 1024 porte sono in genere riservate a servizi di sistema (vedi /etc/services su unix)
■ La porta 80 è riservata in genere al servizio di web server
import java.io.*;
import java.net.*;
public class SocketConnectionHTTP {
BufferedReader in;
PrintWriter out;
Socket s;
public SocketConnectionHTTP(String host, int port) throws IOException {
s = new Socket(host, port);
in = new BufferedReader(
new InputStreamReader(s.getInputStream()));
out = new PrintWriter(s.getOutputStream());
}
public SocketConnectionHTTP() throws IOException { this(Console.readLine("Host: "),
Console.readInt("Port: "));
} …
8
Un esempio: connessione alla porta 80!
■ La lettura e scrittura tramite un socket avviene come su un qualsiasi stream di IO
■ In modo analogo è possibile collegarsi alla porta 25 per il servizo di posta…
…
public String getDocument(String document) throws IOException { String temp = "";
boolean more = true;
if (document==null) document = "/";
out.println ("GET "+ document + " HTTP/1.0\r\n\r\n");
out.flush();
while (more) {
String line = in.readLine();
if (line == null) more = false;
else
temp += line + "\n";
} return temp;
}
public String getDocument() throws IOException {
return getDocument(Console.readLine("Document to get? "));
}
public void close() throws IOException { s.close();
} }
9
Astrazione: connessione URL
■ Per effettuare delle connessioni sia ad un server di posta che ad un server web è possibile utilizzare delle classi che realizzano delle astrazioni sul tipo di protocollo utilizzato
■ L’uso dei socket è nascosto come quello del protocollo HTTP
import java.io.*;
import java.net.*;
public class URLConnectionTest {
BufferedReader in;
URLConnection s;
public URLConnectionTest(String urlName) throws IOException {
URL url = new URL(urlName);
s = url.openConnection();
s.connect();
in = new BufferedReader(
new InputStreamReader(
s.getInputStream() ));
}
public URLConnectionTest() throws IOException { this(Console.readLine("URL: "));
} …
10
Astrazione: connessione URL
■ Per i server di posta esistono le classi del package JavaMail (package non incluso nella distribuzione standard)
…
public String getDocument() throws IOException { int n = 1;
String key;
while ((key = s.getHeaderFieldKey(n)) != null) { String value = s.getHeaderField(n);
System.out.println(key + ": " + value);
n++;
}
System.out.println("---");
System.out.println("getContentType: "
+ s.getContentType());
System.out.println("getContentLength: "
+ s.getContentLength());
…
String temp = "";
boolean more = true;
while (more) {
String line = in.readLine();
if (line == null) more = false;
else temp += line + "\n";
} return temp;
} }
11
ServerSocket
■ Il metodo accept() si mette in attesa di una richiesta di connessione da un socket client
■ Le eccezioni che possono essere sollevate sono del tipo IOException (da catturare e gestire!)
IP Address
Port Server
ServerSocket
ServerSocket s = new ServerSocket(PORT);
[…]
Socket socket = s.accept();
System.out.println("Accettato socket " + socket);
[…]
socket.close();
[…]
s.close();
Crea un nuovo socket sul server per accettazione di una richiesta di connessione
Chiude il socket di una connessione precedentemente accettata
Chiude il server
12
ServerSocket e Socket:
gestione errori
■ E`importante che i socket siano propriamente chiusi al termine di un’applicazione in quando questi sono una risorsa di rete condivisa del sistema
■ La chiusura dei socket deve essere eseguita
indipendentemente dal flusso di esecuzione per questo e`bene utilizzare il costrutto try- finally per garantirne la chiusura
■ La stessa considerazione vale anche per il ServerSocket
[…]
try { […]
String str = in.readLine();
[…]
out.println("OFFERTA");
[…]
}
catch(IOException e) {
System.err.println("IO Exception" + e);
} finally { try { socket.close();
} catch(IOException e) {
System.err.println("Socket not closed");
} } […]
try {
Socket socket = s.accept();
[…]
} finally { s.close();
}
3
13
Un esempio: l’asta
■ Il server è il banditore: accoglie le offerte e comunica se sono accettabili o no, comunica a richiesta la migliore offerta corrente
■ I client sono i partecipanti all’asta, possono richiedere qual’è la migliore offerta (e di chi) e possono effettuare rilanci se il loro budget a disposizione lo consente
14
Un esempio: l’asta
■ Un thread per ogni partecipante all’asta
■ L’offerta è rappresentata da un oggetto che contine l’offerente e l’offerta in denaro
■ La migliore offerta è memorizzata in un oggetto il cui accesso è effettuato mediante un metodo synchronized
■ Per trasmettere un’offerta è necessario convertirla in una stringa (encode)
■ Il server ricostruisce dalla stringa ricevuta un’offerta (decode)
15
Stream di oggetti e Socket
■ Nell’esempio dell’asta i dati di una offerta venivano opportunamente codificati in una unica stringa per essere trasferiti da un client ad un server
■ In Java si puo`pero` utilizzare anche stream di oggetti (ObjectInputStream e OutputObjectStream)
■ In Java e`possibile utilizzare stream di oggetti tramite socket
■ Gli oggetti devono implementare l’interfaccia java.io.Serializable
IP Address
IP Address
Port TPC Port
Server
Client Anche stream di oggetti…
E` importante che possano essere serializzati
16
Stream di oggetti e Socket
■ Importante: la dichiarazione nel client è analoga MA è l’oggetto di tipo ObjectOutputStream va creato prima dell’oggetto di tipo ObjectInputStream pena il deadlock (non è un bug!) […]
ServerSocket s = new ServerSocket(PORT);
[…]
Socket socket = s.accept();
[…]
ObjectInputStream in =
new ObjectInputStream(socket.getInputStream());
ObjectOutputStream out =
new ObjectOutputStream(socket.getOutputStream());
[…]
Offerta nuova = (Offerta)in.readObject();
[…]
out.writeObject("accettata");
[…]
Server
17
Polimorfismo via socket?
■ Gli oggetti trasmessi via stream di oggetti preservano il loro vero tipo
■ A patto che il client (o il server) dispongano della loro definizione
IP Address
IP Address
Port TPC Port
Server
Client