Strumenti Utente

Strumenti Sito


lpr-b:note

Note (LPRb 2007--2008)

Configurazione dell'ambiente Java

Al centro di calcolo esistono tre versioni di Java: la 1.4, la 1.5 e la 1.6. Per far sì che la versione utilizzata sia la 1.x, procedere come segue:

  • se usate bash, nel file .bashrc nella vostra home, inserite le due righe che seguono (alla fine del file):
      export PATH=/usr/local/java/...versionescelta.../bin\:$PATH
      export JAVA_HOME=/usr/local/java/...versionescelta.../bin
  • se usate tcsh, nel file .cshrc nella vostra home, inserite le due righe (come ultime righe del file):

setenv PATH /usr/local/java/…versionescelta…/bin\:$PATH

     setenv JAVA_HOME /usr/local/java/...versionescelta.../bin

Infine, da eclipse, nelle preferenze del progetto, cambiate il runtime settandolo (dopo averlo cercato con l’apposito bottone) all’ambiente che avete scelto.

Thread

Il capitolo sui Thread nella prima parte del libro di testo consigliato copre egregiamente l'argomento. Esiste un tutorial sulla concorrenza in Java che copre anche l'argomento dei thread sul sito della Sun. Infine, questa è una nota che riassume in forma molto compatta tutte le cose sui thread discusse a lezione.

Generics

I generics (terminologia Java per indicare i template C++) sono ormai standard nelle versioni di Java successive alla 1.4. Li useremo abbondamentemente durante il corso. Potete trovare un buon tutorial sul sito della Sun a questo indirizzo (è un file PDF).

Socket TCP/IP

L'utilizzo classico di Socket e ServerSocket è illustrato nel breve tutorial sul sito Sun

Programmino per testare ritorno carrello

Questo programma fa vedere come testare la lettura di un ritorno carrello su un *InputStreamReader*.

Tutorial su util.concurrent

Questo è il tutorial Sun sulla classe java.util.concurrent

Nota sull'apertura di ObjectInput/OutputStream

Quando si utilizzano ObjectStream (in Input e in Output) è necessario che le aperture avvengano nell'ordine giusto. Se sul server si apre un ObjectInputStream con una ObjectInputStream ois = new ObjectInputStream(sock.getInputStream()), occorre che sul client si apra il corrispondente ObjectOutputStream prima dell'apertura dell'ObjectInputStream che implementerà la comunicazione bidirezionale. Se non fosse così, le chiamate new ObjectInputStream(sock.getInputStream()) su client e server si bloccherebbero. Quindi, la sequenza giusta di azioni fra client e server è una cosa tipo:

SERVER                                        CLIENT
...                                           ...
ServerSocket ss = ...      
                                              Socket s = ...
Socket s = ss.accept();
ObjectInputStream ois = 
  new ObjectInputStream(s.getInputStream());  ObjectOutputStream oos = 
                                                new ObjectOutputStream(s.getOutputStream());
// leggi la richiesta                         // scrivi la richiesta
Req r = (Req) ois.readObject();               oos.writeObject(ric);
ObjectOutputStream oos = 
 new ObjectOutputStream(s.getOutputStream());
                                              ObjectInputStream ois = 
                                                new ObjectInputStream(s.getInputStream());
...                                           ...

Programmino ProtocolTester con URL

Questo è il codice per il protocol tester presentato e discusso nella lezione del 26/10.

Comando per controllare lo stato dei socket

Se state utilizzando socket su una macchina (Linux) potete utilizzare il comando netstat per vedere in quale stato si trovino (stato del protocollo TCP, come visto a lezione di reti). Il comando netstat -p tcp fa vedere tutti i dati relativi ai socket TCP sulla macchina. Per esempio:

[dhcp-ospiti3:~/DownloadFolder/Anastasio/remoteserver] marcod% netstat -p tcp
Active Internet connections
Proto Recv-Q Send-Q  Local Address          Foreign Address        (state)
tcp4       0      0  dhcp-ospiti3.cli.65023 hu-in-f99.google.http  CLOSE_WAIT
tcp4       0      0  dhcp-ospiti3.cli.64137 mailserver.di.un.imap  ESTABLISHED
tcp4       0      0  dhcp-ospiti3.cli.63820 fujih3.cli.di.un.ssh   ESTABLISHED
tcp4       0      0  dhcp-ospiti3.cli.63596 mailserver.di.un.imap  ESTABLISHED
tcp4       0      0  dhcp-ospiti3.cli.60752 mailserver.di.un.imap  ESTABLISHED
tcp4       0      0  dhcp-ospiti3.cli.60732 pacifico.di.unip.ssh   ESTABLISHED
tcp4       0      0  localhost.netinfo-loca localhost.986          ESTABLISHED
tcp4       0      0  localhost.986          localhost.netinfo-loca ESTABLISHED
tcp4       0      0  localhost.netinfo-loca localhost.1021         ESTABLISHED
tcp4       0      0  localhost.1021         localhost.netinfo-loca ESTABLISHED
[dhcp-ospiti3:~/DownloadFolder/Anastasio/remoteserver] marcod% 

fa vedere le connessioni aperte sulla mia macchina, per esempio una connessione fra la port 60732 e la porta ssh (23) di pacifico.

Se per esempio state utilizzando un server che pubblica un socket sulla porta 54321, con il comando nestat -p tcp | grep 54321 potete osservarne lo stato:

[dhcp-ospiti3:~/DownloadFolder/Anastasio/remoteserver] marcod% netstat -a | grep 54321
tcp46      0      0  *.54321                *.*                    LISTEN
[dhcp-ospiti3:~/DownloadFolder/Anastasio/remoteserver] marcod% 

Notare che il socket è marcato come tcp46, ovvero che può lavorare sia con TCP/IPv4 che con TCP/IPv6. Dipenderà dalla connessione se si utilizzarà un protocollo o l'altro. Se lo stato fosse CLOSE_WAIT (come nella prima riga dell'uscita del primo comando) siete nella condizione in cui il socket è stato chiuso e non si può ancora riutilizzare l'indirizzo perchè si attende il timeout che escluderà che pacchetti diretti a questo socket siano intercettati da un nuovo socket aperto sulla stessa porta. Per esempio, dopo aver lanciato un client che si connette alla 54321, e dopo che il client sia terminato, otterremo:

Proto Recv-Q Send-Q  Local Address          Foreign Address        (state)
tcp4       0      0  localhost.54321        localhost.65226        CLOSE_WAIT
tcp46      0      0  *.54321                *.*                    LISTEN

C'e' ancora la possibilità di connettersi alla 54321 (che è listening) mentre la connessione precedente (che aveva avuto come porta effimera del client la 65226) è in CLOSE_WAIT. Si veda la documentazione completa di nestat con man netstat.

Classe ODP (Object Datagram Packet)

Questo è il sorgente della classe ODP, discussa a lezione, che si può utilizzare per l'invio e la ricezione di Object mediante DatagramPacket. La classe è stata modificata rispetto a quanto presentato a lezione, in verità, perchè è stato aggiunto il controllo sulla dimensione del pacchetto. I metodi sono stati trasformati in modo dal lanciare eccezzioni in caso di problemi. Verificatene l'utilizzabilità e modificatela pure a vostro piacimento.

DatagramSocket che perde una percentuale di pacchetti

Se volete testare programmi che utilizzano DatagramSocket per la spedizione di pacchetti UDP utilizzate questa implementazione. Vedi anche pagina degli esercizi. L'implementazione perde una percentuale di pacchetti stabilita dall'utente (il 10% per default).

Documentazione su RMI

Esiste un tutorial sul sito Sun/Java che spiega esaudientemente tutto quanto serve per realizzare programmi Java con RMI. Un altro mini tutorial decente si trova su javacoffebreak. Informazioni dettagliate sull'uso delle policy si trovano anche su The Java Developers Almanac (anche se queste fanno ancora riferimento a versioni vecchie di Java).

Security Managers con RMI

Quando si voglia (o si debba) usare un SecurityManager per permettere caricamento dinamico di classi con RMI, si deve specificare un file con i permessi necessari alla polocy che si vuole implementare secondo il formato standard definito da Java (pagina sito Sun/Java). In questo caso, il programma deve essere lanciato definendo a riga di comando quale file di policy deve essere consultato. A tale scopo si usa la sintassi

 java -Djava.security.policy=FileCheContieneLaPolicy nomeDellaClasseMain

Da notare che apparentemente una

grant {
 permission  java.security.AllPermissions; 
}; 

non da' i permessi necessari alla lookup dell'oggetto remoto che vanno pertanto specificati con una permission esplicita tipo:

 permission java.net.SocketPermission "fujih1.cli.di.unipi.it", "connect,resolve";

dove il nome della macchina può essere sostituito dal wildcard “*”

Esempio commentato sull'uso delle callback con RMI

Su questo link trovate un esempio di codice master/worker realizzato con RMI sia senza che con le callback.

lpr-b/note.txt · Ultima modifica: 05/12/2007 alle 08:43 (17 anni fa) da Marco Danelutto