Programmazione di rete in Java - LIA

Programmazione di rete in Java
Java fornisce per la gestione della comunicazione le
classi del package di networking java.net
Gerarchia delle classi in Java
Package java.net
le socket rappresentano il terminale (end point)
di un canale di comunicazione bidirezionale
Un Client e un Server su macchine diverse possono
comunicare sfruttando due diversi tipi di modalità di
comunicazione
• con connessione, in cui viene stabilita una
connessione tra Client e Server (esempio, il
sistema telefonico)
Uso di socket STREAM
• senza connessione, in cui non c’è
connessione e i messaggi vengono recapitati
uno indipendente-mente dall’altro (esempio, il
sistema postale)
Uso di socket DATAGRAM
classi per SOCKET INTERNET
• con connessione
• classe Socket, per socket lato Client,
con connessione (TCP)
• classe ServerSocket, per socket lato
Server, con connessione (TCP)
• senza connessione
• classe DatagramSocket, per socket (C/S)
senza connessione (UDP)
C/S in Java: Socket in Java - 1
Le classi sono state significativamente estese
dalla diverse versioni delle JVM
per tenere conto delle diverse necessità applicative
C/S in Java: Socket in Java - 2
Sistema di NOMI
NOMI per SOCKET
Necessità
di
definire
un
sistema
identificazione delle entità messe in gioco
Una macchina è identificata univocamente da un
indirizzo IP (4 byte / 32 bit) (livello IP)
La porta è un numero intero di 16 bit (astrazione
fornita dal TCP e da UDP)
di
Un’applicazione distribuita è costituita da
processi distinti per località che comunicano e
cooperano attraverso lo scambio di messaggi, per
ottenere risultati coordinati
Il primo problema da affrontare riguarda la
identificazione dei processi (il Client o il Server)
nella rete
Per ogni processo bisogna definire
un NOME GLOBALE
visibile in modo univoco e sempre non ambiguo
“nome” della macchina +
“nome” del processo all’interno della macchina
Gli endpoint di processo (socket) sono tipicamente
locali al processo stesso
(livello applicativo o sottostante fino a sessione)
Il problema è risolto dai livelli sottostanti di protocollo
per le socket nel dominio Internet
i nomi di trasporto (TCP, UDP) e rete (IP)
C/S in Java: Socket in Java - 3
NOME GLOBALE
I messaggi sono consegnati
su una specifica porta
di una specifica macchina,
non direttamente a un processo
NOME LOCALE
Un processo si lega a una porta per ricevere (o
spedire) dei messaggi
o anche più processi si collegano
In questo modo è possibile identificare un processo
senza dover conoscere il suo process identifier (pid)
Un indirizzo IP e una porta possono
rappresentare un endpoint di un canale di
comunicazione
NOME IP
NUMERO PORTA
livello network - OSI 3
livello trasporto - OSI 4
C/S in Java: Socket in Java - 4
Caso di Server sequenziale o iterativo
NOMI GLOBALI
Numeri IP => vedi protocollo IP
indirizzo IP: ad es. 137.204.57.186
Numeri di Porta
porte 4 cifre hex: XXXXh
spesso espresse con unico decimale
una richiesta alla volta (con connessione o
meno)
I tempi di risposta al servizio aumentano ==>
servizi brevi
server sequenziale senza connessione
servizi senza stato (che introduce ritardi) e non
soggetti a guasti
ad es. 153, 2054
unica coda
C1
Funzione fondamentale delle porte è identificare un
servizio
risposta sulla
porta cliente
Cn
I numeri di porta minori di 1024 sono riservati
(well-known ports, o reserved)
sono standardizzati i servizi offerti dai processi
che a tale porta sono legati
Per esempio, il servizio Web è identificato dalla
porta numero 80, cioè il processo server di un
sito Web deve essere legato alla porta 80, su cui
riceve i messaggi con le richieste di pagine html
Altri esempi:
porta 21 per ftp,
porta 23 per telnet,
porta 25 per mail,…
#portaserver
#portac1
unica coda iniziale
risposta sulla
C/S in Java: Socket in Java - 5
della
Processo
Server
Controllore
porta cliente
#portaserver
Cn
Azioni
unica connessione stabilita
C1
La richiesta di un servizio a un processo server non
richiede quindi la conoscenza del suo pid, ma solo
della porta e IP (nomi globali)
Azioni
server sequenziale con connessione
servizi con requisiti di reliability
limitando lo stato (uso di TCP)
difficile realizzazione pratica
overhead delle azioni di controllo
connessione
C1
Processo
Server
Controllore
#portac1
#portaserver
C/S in Java: Socket in Java - 6
SERVER concorrente singolo processo
non parallelo
Server concorrente
più richieste alla volta
(multi o singolo processo)
SERVER PARALLELO processi multipli
uso di processi multipli, un master server
generazione di processi interni per ogni servizio
massimo parallelismo per servizi non interferenti
Si deve garantire che il costo di generazione del
processo non ecceda il guadagno ottenuto
in caso di connessione e stato (limitati)
realizzato con un unico processo che produce effetti
di concorrenza dal punto di vista dei clienti
l'unico processo master deve considerare tutte le
richieste ed servirle al meglio (mantenendo le
connessioni)
Facciamo il caso di connessione (ma anche senza)
Soluzione con processi creati in precedenza
che consentano di essere velocemente smistati
al servizio necessario
numero prefissato di processi iniziali e altri
creati su necessità e mantenuti per un certo
intervallo
Server parallelo senza connessione
#porta1
C1
richieste
iniziali
Cn
C1
Processo
Server
Controllore
#portaserver
#portan
connessione
#porta1
Azioni
C1
Processo
Server
Controllore
Cn
#portaserver
Ci
#portan
generazione
processo
connessione
Porte differenziate
C1
Processo
Server
Controllore
Cn
#porta1
Azioni
Ci
Unico Processo Server
Processi Client attivi
#portan
Necessità di rispondere in modo veloce alle richieste
successive e sollecitazioni
Cn
Processi Client attivi
Processi Server
Un canale unico e un processo per ogni servizio
C/S in Java: Socket in Java - 7
(REALIZZABILE IN JAVA???)
C/S in Java: Socket in Java - 8
SOCKET per DATAGRAM
SOCKET DATAGRAM
Le socket DATAGRAM permettono a due thread di
scambiarsi messaggi senza stabilire una
connessione tra i thread convolti
Necessità di protocollo
Scambio di messaggi da socket datagram
meccanismo di comunicazione non è affidabile
possibili perdite di messaggi (per problemi di rete)
consegna non in ordine
a causa del protocollo UDP
Vi è un solo tipo di socket DATAGRAM
sia per il Client sia per il Server
La classe java.net.DatagramSocket
public final class
DatagramSocket extends Object
Costruttore (ce ne sono altri)
DatagramSocket(
InetAddress localAddress,
int localPort) throws...
il costruttore DatagramSocket crea socket UDP e fa
un binding locale a porta e nome IP
SCAMBIO MESSAGGI usando send e receive
sock.send(DatagramPacket);
sock.receive(DatagramPacket);
Si usano sempre classi accessorie di supporto
C/S in Java: Socket in Java - 9
Socket invio
Socket
Socket
Porta1
Nome IP invio
Socket ricezione
Socket
Socket
Porta2
Nome IP ric.
Le due socket messe in gioco devono essere state
x inizializzate correttamente (create)
x devono conoscersi
In particolare chi invia: il mittente deve specificare
nel messaggio che vuole comunicare con un
ricevente (e una sua socket)
Si devono specificare informazioni
di tipo applicativo
parte dati
il messaggio (o lo spazio per il messaggio)
di controllo comunicazione
parte controllo
il nodo del ricevente, la porta per arrivare alla
socket del ricevente
Nessuna garanzia nelle operazioni a causa del
protocollo di supporto (UDP e IP)
C/S in Java: Socket in Java - 10
Classi Accessorie
Parte Dati
Dati utente
DatagramPacket
Classe introdotta per usare e preparare
datagrammi che consentono di specificare
cosa comunicare
(parte dati)
come comunicare e con chi (parte controllo)
Una istanza datagramma specifica un array di
byte da/su cui scrivere e con indicazioni di
comunicazione con diversi costruttori
Parte controllo
Interi per la porta e InetAddress
InetAddress
classe per gli indirizzi IP
ad esempio
public static InetAddress getByName
(String hostname);
solo alcuni metodi pubblici statici
(public static):
getByName(String hostname);
fornisce un oggetto InetAddress per l’host
specificato (null default locale)
InetAddress[ ] getAllByName(String hostname);
fornisce un array di oggetti InetAddress per più
indirizzi IP sullo stesso nome logico
InetAddress getLocalHost();
fornisce InetAddress per macchina locale
C/S in Java: Socket in Java - 11
Tramite un Contenitore unificato
DatagramPacket(
byte [] buf, // array di byte dati
int offset, // indirizzo inizio
int length, // lunghezza dati
InetAddress address, // indirizzo IP
int port);
// porta
che prevede anche molti altri costruttori
e molte funzioni di utilità come
getAddress(),
setAddress(InetAddress addr)
getPort(),
setPort(int port)
getData(),
setData(byte[] buf), …
Nel DatagramPacket si deve considerare l’uso a
secondo della funzione che stiamo invocando:
x in invio dobbiamo avere una area su cui l’utente
possa mettere i dati e l'area per accogliere le
informazioni di controllo sul ricevente (fornite dal
mittente del pacchetto).
x in ricezione dobbiamo avere preparato tutto per
ricevere tutte le informazioni, sia per la parte dati,
sia per la parte di controllo (indirizzo del mittente)
C/S in Java: Socket in Java - 12
Socket Multicast
Schema di comunicazione
Creazione socket
Sono anche possibili ulteriori classi per inviare
messaggi multicast e gruppi di multicast
DatagramSocket socket =
new DatagramSocket();
Preparazione gruppo: IP classe D e porta libera
Preparazione informazione da inviare e invio
byte[] buf = {'C','i','a','o'};
InetAddress addr = InetAddress.
getByName("137.204.59.72");
int port = 1900;
DatagramPacket packet =
new DatagramPacket
(buf, buf.length, addr, port);
socket.send(packet);
Preparazione, attesa informazione, e ricezione
int report;
InetAddress recaddress;
byte [] result = new byte [200];
socket.receive(packet);
recport = packet.getPort();
recaddress = packet.getAddress();
result = packet.getData();
InetAddress gruppo = InetAddress.
getByName("229.5.6.7");
MulticastSocket s =
new MulticastSocket(6666);
Operazioni di ingresso/uscita dal gruppo
// unisciti al gruppo ...
s.joinGroup(gruppo);
byte[] msg = {'H', 'e', 'l', 'l', 'o'};
DatagramPacket packet =
new DatagramPacket
(msg, msg.length, gruppo, 6666);
s.send(packet);
// ottenere i messaggi inviati
byte[] buf = new byte[1000];
DatagramPacket recv =
new DatagramPacket
(buf, buf.length);
s.receive(recv);
...
// uso delle informazioni
C/S in Java: Socket in Java - 13
// esci dal gruppo ...
s.leaveGroup(group);
C/S in Java: Socket in Java - 14
SOCKET per STREAM
SOCKET per STREAM
Le socket STREAM sono i terminali di un canale di
comunicazione virtuale creato prima di comunicare tra
il Client e il Server
La comunicazione avviene in modo
bidirezionale,
affidabile,
con dati (byte) consegnati in sequenza una sola volta
(modalità FIFO come sulle pipe di Unix)
e se non consegnati???
semantica at-most once
La connessione tra i processi Client e Server è
definita non dai processi che devono comunicare ma
da una quadrupla univoca
<protocollo; indirizzo IP Client; porta Client;
indirizzo IP Server; porta Server>
Nel caso delle socket STREAM, il protocollo di
comunicazione sottostante è il protocollo TCP (+ IP)
• TCP è un protocollo di trasporto, livello 4 OSI e fornisce
l’astrazione porta
• IP è un protocollo di rete, livello 3 OSI e identifica
univocamente ogni macchina collegata alla rete
Internet
La comunicazione tra Client e Server su stream
segue uno schema asimmetrico e il principio della
connessione (relative API diverse)
Questa considerazione ha portato al progetto di due
tipi di socket diverse una per il Client e una per il
Server
C/S in Java: Socket in Java - 15
Protocollo di Comunicazione con Connessione in Java
Richiesta di
connessione
Client Application
Socket
Socket
Server
Server
Socket
Socket
Server
Application
Client Application
Socket
Socket
Socket
Socket
Socket
Socket
Classi distinte per ruoli Cliente e Servitore
La classe java.net.Socket
La classe java.net.ServerSocket
I costruttori delle classi tendono a nascondere i
dettagli realizzativi
I costruttori creano la socket, la legano a una
porta locale e la connettono a una porta della
macchina remota
(Unix API più complesse e complete:
vedi socket, bind, connect)
C/S in Java: Socket in Java - 16
Lato CLIENTE
Operazioni CLIENTE - costruttori
La classe Socket consente di creare una socket
con connessione, stream (TCP) per il
collegamento di un Client a un Server
socket è detta anche socket “attiva”
public Socket(InetAddress remoteHost,
int remotePort) throws IOException;
Crea una socket stream cliente e la collega alla
porta specificata della macchina all’indirizzo IP dato
(equivale in Unix a: socket, bind, connect)
I costruttori della classe creano la socket, la legano
a una porta locale e ...
la connettono a una porta di una macchina
remota su cui sta il server
La
connessione
permette
poi
comunicazione bidirezionale (full duplex)
Server
Server
Socket
Socket
una
Server
Application
Client Socket
Socket
Socket
Porta
Socket
Nome IP
Si noti che la creazione della socket produce in
modo atomico anche la connessione al server
corrispondente (deve essere presente)
(Unix API più complesse e complete: vedi socket,
bind, connect)
C/S in Java: Socket in Java - 17
public Socket(String remoteHost,
int remotePort) throws IOException;
Crea una socket stream cliente e la collega alla
porta specificata della macchina di nome logico
remoteHost
public Socket(InetAddress remoteHost,
int remotePort,
InetAddress localHost,
int localPort)
throws IOException;
Crea una socket stream cliente e la collega
sia a una porta della macchina locale
(se localPort vale zero, il numero di porta è
scelto automaticamente dal sistema)
sia a una porta della macchina remota
(macchine multihomed)
La creazione della socket produce in modo atomico
anche la connessione al server corrispondente
o lancia la eccezione opportuna
C/S in Java: Socket in Java - 18
Connessioni
Operazioni CLIENTE - supporto
la creazione di una socket a stream se va a buon
fine produce una connessione bidirezionale a byte
(stream) tra i due processi interagenti e impegna
risorse sui nodi e tra i processi
Per ottenere informazioni sulle socket si possono
utilizzare i metodi aggiuntivi
APERTURA ottenuta con il costruttore
in modo implicito
CHIUSURA
operazione
necessaria per non impegnare
troppe risorse di sistema
Le risorse diventano le connessioni:
costa definirle e crearle, come distruggerle
e mantenerle
Si tendono a mantenere le sole connessioni
necessarie
Limiti alle aperture contemporanee di sessioni
Il numero di connessioni che un processo
(Client o Server) può aprire è limitato, =>
si chiudono le connessioni non utilizzate
Il metodo close() chiude l’oggetto socket
disconnette il Client dal Server
public synchronized void close()
C/S in Java: Socket in Java - 19
public InetAddress getInetAddress();
restituisce l’indirizzo della macchina remota a cui
la socket è connessa
public InetAddress getLocalAddress();
restituisce l’indirizzo della macchina locale
public int getPort();
restituisce il numero di porta sulla macchina
remota cui la socket è connessa
public int getLocalPort();
restituisce il numero di porta sulla macchina locale
a cui la socket è legata
Esempio:
int porta = oggettoSocket.getPort();
Client Socket
Socket
Socket
e
Porta
Nome IP
Socket
Server
sul Socket
Server
Porta
Server
Application
Socket
Nome IP
C/S in Java: Socket in Java - 20
Uso di stream tipici di Java
Esempio
Operazioni di comunicazione su stream
Client di echo (il Server Unix è sulla porta 7)
Lettura o scrittura da/su una socket con i metodi:
public InputStream getInputStream()
ritorna l’input stream per leggere dei byte dalla
socket
public OutputStream getOutputStream()
ritorna l’output stream per scrivere dei byte sulla
socket
try {
oggSocket = new Socket(hostname, 7);
/* input ed output sugli endpoint
della connessione via socket */
out = new PrintWriter
(oggSocket.getOutputStream(),true);
in = new BufferedReader
(new InputStreamReader
(oggSocket.getIntputStream());
/* lettura da input */
userInput = new BufferedReader(
new InputStreamReader(System.in));
I due metodi restituiscono un oggetto stream che
incapsula il canale di comunicazione
(di classi InputStream e OutputStream)
. . .
Attraverso gli stream si possono spedire/ricevere
solo byte, senza nessuna formattazione
naturalmente i byte arrivano ordinati non duplicati
(non possono arrivare byte successivi, senza
che arrivino i precedenti)
i dati arrivano al più una volta
at-most-once
e in caso di errore?
nessuna conoscenza
while((oggLine = userInput.readLine())
!= null)
/* lettura input fino a fine file */
{
out.println(oggLine);
System.out.println(in.readLine());
}
oggSocket.close();
} // fine try
catch (IOException e)
{ System.err.println(e);}
Altri oggetti possono incapsulare questi stream, per
fornire funzionalità di più alto livello
(es., DataInputStream)
...
C/S in Java: Socket in Java - 21
C/S in Java: Socket in Java - 22
La classe java.net.ServerSocket
Costruttori per il server
Lato server
public ServerSocket(int localPort)
throws IOException, BindException;
crea una socket in ascolto sulla porta specificata
La classe ServerSocket definisce una socket
capace di accettare richieste di connessione
provenienti dai diversi Client
più richieste di connessione pendenti allo
stesso tempo e
più connessioni aperte contemporaneamente
Definisce anche la lunghezza della coda in cui
vengono messe le richieste di connessione non
ancora accettate dal server
Una volta stabilita la connessione
(ottenuta dal server tramite il metodo accept)
la trasmissione dei dati avviene attraverso un
normale oggetto Socket del server (restituito dalla
accept)
Al momento della creazione si effettuano
implicitamente le operazioni più elementari visibili
in UNIX, come socket, bind e listen
public ServerSocket(int localPort,
int count)
throws IOException, BindException;
crea una socket in ascolto sulla porta specificata
con una coda di lunghezza count
Le richieste accodate non sono servite
automaticamente
=>
necessità di un API che esprima la volontà di
servizio
Il server gioca un ruolo "passivo"
deve specificare la coda delle possibili richieste
ed aspettare i clienti
comincia a decidere con la introduzione
volontaria della primitiva di accettazione
esplicita
ACCEPT di una connessione
C/S in Java: Socket in Java - 23
C/S in Java: Socket in Java - 24
ACCEPT di connessione
Informazioni sulle socket connesse:
Il Server si mette in attesa di nuove richieste di
connessione chiamando il metodo accept()
public InetAddress getInetAddress()
restituisce l’indirizzo della macchina locale a cui la
socket server è connessa
public int getLocalPort()
restituisce il numero di porta sulla macchina locale
La invocazione di accept blocca il Server fino
all’arrivo di una richiesta
Quando arriva una richiesta, accept stabilisce una la
reale connessione tra il Client e un nuovo oggetto
Socket restituito da accept e che rappresenta lo
stream con il cliente
public Socket accept()
throws IOException;
La accept restituisce un oggetto della classe
Socket su cui avviene la comunicazione tra Client e
Server
la chiamata di accept mette il servitore in attesa di
richieste di connessione
Tipicamente se non ci sono ulteriori richieste, il
servitore si blocca in attesa
Se c’è almeno una richiesta, si sblocca la primitiva
e si crea la connessione per questa
La trasmissione dei dati avviene con i metodi visti per
il lato Client
in modo del tutto indifferente in uno o l'altro verso
della connessione
i due endpoint sono del tutto omogenei
(uso di protocollo TCP)
C/S in Java: Socket in Java - 25
Server daytime (il Server Unix su porta 13)
...
oggServer =
new ServerSocket(portaDaytime);
try {
/* il server alla connessione invia
la data al cliente */
while (true)
{ oggConnessione = oggServer.accept();
out = new PrintWriter
(oggConnessione.getOutputStream(),
true);
Date now=new Date();
// produce la data
out.write(now.toString()+ "\r\n");
oggConnessione.close();
}
}
catch (IOException e)
{ oggServer.close();
oggConnessione.close();
System.err.println(e);
}
. . .
C/S in Java: Socket in Java - 26
Server Parallelo con connessione
Esempio possible
Remote CoPy (RCP)
Richi
es
ta di
conn
ession
e
Thread
Server
(padre)
Comunica
zi
one Client/
accept (); <attesa su ServerSocket>
<generazione thread>
<padre continua>
Server
< servizio della richiesta
uso di Socket >
Nuovo
Thread
Alla accettazione il servitore può generare
una nuova attività responsabile del servizio
(che eredita la connessione nuova)
Il servitore principale può
aspettare nuove richieste e
servire nuove operazioni
Si realizzi un’applicazione distribuita Client/Server per
eseguire la copia remota (remote copy, rcp) di file
Progettare
sia il programma client
sia il programma server
Il programma Client deve consentire la invocazione:
rcp_client nodoserver portaserver
nomefile nomefiledest
nodoserver e portaserver indicano il nome Server e
nomefile è il nome di un file presente nel file system
della macchina Client
Il processo Client deve inviare il file nomefile al
Server che lo scrive nel direttorio corrente con nome
nomefiledest
La scrittura del file nel direttorio specificato deve
essere eseguita solo se in tale direttorio non è
presente un file con lo stesso nome, evitando di
sovrascriverlo
Uso di connessione: il file richiede di trasferire
anche grosse moli di dati e in ordine
La connessione aperta dal cliente consente al server
di coordinarsi per la richiesta del file che viene
inviato
!Versione non ottimizzata da migliorare!
C/S in Java: Socket in Java - 27
C/S in Java: Socket in Java - 28
RCP Client
RCP Server iterativo sequenziale
Estratto del client
...
...
rcpSocket = new Socket(host,porta);
OutSocket = new DataOutputStream
(rcpSocket.getOutputStream());
InSocket =
new DataInputStream
(rcpSocket.getInputStream());
OutSocket.writeUTF (NomeFileDest);
Risposta = InSocket.readUTF();
System.out.println(Risposta);
if (Risposta.equalsIgnoreCase
("MSGSrv: attendofile") == true)
{FDaSpedDescr = new File(NomeFile);
FDaSpedInStream = new
FileInputStream(FDaSpedDescr);
byte ContenutoFile [] = new byte
[FDaSpedInStream.available()];
FDaSpedInStream.read(ContenutoFile);
StrDatiOutSocket.write
(ContenutoFile);
}} // file letto tutto in un colpo?
catch (IOException e)
{System.err.println(e);}
rcpSocket.close();
...
try {
rcpSocketSrv = new ServerSocket(Porta);
System.out.println("Attesa su porta" +
rcpSocketServer.getLocalPort());
while(true)
{SocketConn = rcpSocketSrv.accept();
System.out.println("con " + Socketconn);
OutSocket = new DataOutputStream
(SocketConn.getOutputStream());
InSocket = new DataInputStream
(SocketConn.getInputStream());
NFile = InSocket.readUTF ();
FileDaScrivere = new File(NFile);
UTF formato standard Unified Transformation Format
per maggiore portabilità
C/S in Java: Socket in Java - 29
if(FileDaScrivere.exists() == true)
{ OutSocket.writeUTF(
"MSGSrv: file presente, bye");
} else
{ OutSocket.writeUTF(
"MSGSrv: attendofile");
byte ContntFile[] = new byte [1000];
InSocket.read(ContntFile);
FileOutputStream = new
FileOutputStream (FileDaScrivere);
FileOutputStream.write(ContntFile);
} SocketConn.close();
} // file letto tutto nel buffer ?
}
catch (IOException e)
{System.err.println(e);} ...
C/S in Java: Socket in Java - 30
RCP Server concorrente parallelo
RCP Server Processi Figli
...
try
{
...
rcpSocket =
new ServerSocket(Porta);
System.out.println("Attesa su porta" +
rcpSocket.getLocalPort());
public class rcp_servizio
extends Thread {
...
rcp_servizio(Socket socketDaAccept)
{rcpSocketSrv = socketDaAccept;}
while(true)
{
rcpSocketConn = rcpSocket.accept();
threadServizio = new rcp_servizio
(rcpSocketConn);
threadServizio.start();
}
}
catch (IOException e)
{System.err.println(e);}
Si genera un nuovo processo per ogni connessione
generata e su questa avviene la interazione
Una socket usata è visibile da tutti i thread
(condivisione risorse): la prima close chiude la
socket definitivamente per tutti i thread
Si noti che le socket usate dai thread sono tutte
considerate impegnate per il sistema di supporto
???e se c'è un limite al numero di socket aperte
per processo??? (e le porte?)
C/S in Java: Socket in Java - 31
public void run() {
System.out.println("thread numero " +
Thread.currentThread());
System.out.println(""Connesso con" +
+ rcpSocketSrv);
try
{OutSocket= new DataOutputStream
(rcpSocketSrv.getOutputStream());
InSocket = new DataInputStream
(rcpSocketSrv.getInputStream());
NomeFile = InSocket.readUTF();
FileDaScrivere = new File(NomeFile);
if(FileDaScrivere.exists () == true)
/* in caso le cose siano terminate
senza invio /*
{ OutSocket.writeUTF(
"MSGSrv: file presente, bye");
}
C/S in Java: Socket in Java - 32
/* solo in caso si consenta di
trasmettere il file /*
else
/* scrittura effettiva del file */
{
OutSocket.writeUTF(
"MSGSrv: attendofile");
byte ContentFile [] =
new byte [1000];
InSocket.read(ContentFile);
FileDaScrivereOutputStream = new
FileOutputStream (FileDaScrivere);
FileDaScrivereOutputStream.write
(ContentFile);
}
/* chiusura della connessione e
terminazione del servitore specifico
*/
rcpSocketSrv.close();
System.out.println(
"Fine servizio thread numero " +
Thread.currentThread());
}
catch (IOException e)
{ System.err.println(e); exit(1);}
...
C/S in Java: Socket in Java - 33
Chiusura delle Socket
Le socket in Java impegnano non solo il loro livello
applicativo, ma anche una serie di risorse di
sistema che sono collegate e necessarie per la
operatività
La chiusura è quindi necessaria sempre per
dichiarare la non necessità di mantenere risorse
non più in uso
In casa di una socket chiusa, le risorse sono
mantenute per un certo tempo (in dipendenza dalla
importanza delle operazioni)
In caso di socket connessa chiusa, la memoria viene
mantenuta per continuare a spedire informazioni da
inviare al pari
Il pari si accorge di questo tramite:
- eventi che gli vengono notificati in caso di
operazioni (tipo lettura o scrittura sulla sua socket)
- eccezioni o predicati
Si vedano alcune funzioni come:
isClosed ();
isConnected ();
isInputShutdown ();
isOutputShutdown ();
C/S in Java: Socket in Java - 34
Opzioni delle Socket
URL
Si esplorino le opzioni delle socket in Java con
funzioni definite
SetSoTimeout (int timeout) throws...
la lettura da socket (es., read()) è bloccante.
Questa opzione definisce un timeout (in msec),
trascorso il quale si sblocca la read (ma viene
lanciata una eccezione da gestire)
timeout a zero, nessuna sospensione
SetSendBufferSize (int size) throws...
il buffer di invio dello stream può essere variato
SetReceiveBufferSize (int size)
il buffer di invio dello stream può essere variato
SetReuseAdddress ()
si possono collegare più processi (e socket) ad un
certo indirizzo fisico
Solo socket a stream
SetSoLinger (boolean on, int linger)
dopo la close, il sistema tenta di consegnare i
pacchetti ancora in attesa di spedizione. Questa
opzione permette di scartare i pacchetti in attesa
(linger in sec)
SetTcpNoDelay (boolean on) throws ...
il pacchetto è inviato immediatamente, senza
bufferizzare
SetKeepAlive (boolean on) throws...
abilita, disabilita la opzione di keepalive
Sono previste le get corrispondenti
le opzioni sono disponibili nella classe SocketOptions
C/S in Java: Socket in Java - 35
Inoltre visto l'ampio uso di Indirizzi Web
La classe
java.net.URL
La classe URL descrive le risorse Internet
http://deis.unibo.it/index.html
protocol
handler
content
handler
metodo
getContent
Scaricamento di una pagina
...
URL deis = new URL
("http://www.deis.unibo.it/");
BufferedReader in =
new BufferedReader(
new InputStreamReader(
deis.openStream()));
String inLine;
while ((inLine = in.readLine())!=null)
System.out.println(inLine);
in.close();
...
possibilità di agganciarsi dinamicamente ad un URL
e di gestire il trasferimento via protocollo HTTP
C/S in Java: Socket in Java - 36