Sunteți pe pagina 1din 25

Aplicatii de retea. Socluri. URL.

1. Protocoale si porturi. Modelul client server. 2. Modelul de comunicatie orientat pe conexiune. Clasele Socket si ServerSocket 3. Modelul de comunicatie neorientat pe conexiune. Clasele DatagaramSocket si DatagramPacket 4. URL Clasele din pachetul java.net se impart in doua categorii, clase pentru socluri si clase care lucreaza cu URL (Uniform Resource Locators). Soclurile Java faciliteaza accesul la protocoalele standard utilizate in comunicarea intre calculatoarele gazda de pe Interent.

1. Protocoale si porturi. Modelul client server.


Protocoale
Inainte sa intram in detaliile posibilitatilor oferite de limbajul Java pentru scrierea aplicatiilor de retea trebuie sa cunoastem niste lucruri despre reteaua Internet. Internetul functioneaza pe un sistem de protocoale numit TCP/IP (Transport Control Protocol/Internet protocol)

Aceste protocoale stabilesc regulile cu ajutorul carora doua calculatoare comunica intre ele. Protocoalele sunt standarde de care se ocupa IETF ( Internet Engineering Task Force). Java implementeaza protocoalele de nivel superior ale stivei de protocoale TCP/IP. Astfel faciliteaza utilizarea protocoalelor HTTP (HyperText Transfer Protocol) si FTP( File Transfer Protocol). Astfel programatorul va utiliza niste clase si interfete predefinite, fara a cunoaste detaliile de implementare ale acestora. Nu trebuie sa

cunoastem structurile de date utilizate de acest sistem de protocoale, nici metodele utilizate pentru transmiterea si receptionarea secventelor de octeti.

Modelul client server


Serverul este o aplicatie care ofera servicii clientilor sositi prin retea. Serverele ofera o gama variata de servicii. Serverul cel mai cunoscut este serverul Web, care furnizeaza documentele cerute de catre clienti. Un alt serviciu cunoscut este posta electronica, care utilizeaza protocoalele SMPT (Simple Mail Transfer Protocol) si IMAP4 (Internet Mail Access Protocol). Pe principiul client-server funnctioneaza si protocoalele NFS (Network File Service) si FTP sau serviciul de nume de domenii DNS (Domain Name Service) si serviciul de informatii despre retea NIS (Network Information Services). Trebuie sa amintim si serviciul care permite logarea la un calculator aflat la distanta: TELNET si RLOGIN. Arhitectura client-server este instrumentul de baza in dezvoltarea aplicatiilor de retea. Clientul este o aplicatie care utilizeaza serviciile oferite de catre un server. Pentru a putea realiza acest lucru, clientul trebuie sa cunoasca unde se afla serverul in retea si cum trebuie comunicat cu acesta si ce servicii ofera. Deci daca un client doreste o comunicare cu serverul, trebuie sa cunosca trei lucruri: adresa server portul server utilizat pentru comunicare protocolul de comunicatie utilizat de server Daca aceste date ne stau la dispozitie, putem realiza comunicatia cu serverul.

Porturi si socluri
Porturile si soclurile reprezinta mecanismul prin care se realizeaza legatura cu un server. Porturile reprezinta o poarta la care sunt primiti clientii pentru un anumit serviciu. De exemplu la aceeasi adresa se pot oferi diferite servicii, acestea oferindu-se la porturi diferite. Acelasi calculator (cu o singura adresa IP) poate sa ne ofere oricate servicii doreste. Clientii care apeleaza la serviciile acestui calculator vor utiliza aceeasi adresa, indiferent la care serviciu apeleaza, si toti clientii care doresc utilizarea unui anumit serviciu vor utiliza acelasi port. Un numar de port este un numar inreg din intervalul 1-9999. IETF defineste serviciile oferite pe porturile 1-1024. De obicei serviciile HTTP sunt oferite la portul 80, cele de FTP la portul 21, Telnet la 23 etc. Un soclu este un nod abstract de comunicatie. Soclurile reprezinta o interfata de nivel scazut pentru comunicarea in retea. Soclurile permit comunicarea intre procese aflate pe acelasi calculator sau pe calculatoare diferite din retea. Mecanismul de socluri a fost definit prima data in BSD UNIX. Java suporta trei tipuri de socluri. Clasa Socket utilizeaza un protocol orientat pe conexiune (TCP), clasa DatagramSocket utilizeaza protocolul UDP la nivelul transport, care este un protocol neorientat pe conexiune. O alta varianta a DatagramSocket este MulticastSocket utilizat pentru a trimite date deodata la mai multi receptori. Soclurile utilizeaza fluxuri de date (streamuri) pentru a trimite si a receptiona mesaje.

2. Modelul de comunicatie orientat pe conexiune. Clasele Socket si ServerSocket


Acest model se bazeaza pe protocolul TCP. Intr-o aplicatie retea intotdeauna avem doua parti: o parte client care initializeaza conversatia si trimite cereri, si o parte server care primeste cererile si raspunde la acestea. Clientul creaza un soclu pentru a initia conversatia si trebuie sa cunoasca serverul caruia ii adreseaza cererea, iar serverul trebuie sa fie pregatit pentru a receptiona aceste cereri. In momentul receptionarii mesajului creaza un soclu pe partea serverului, soclu care va facilita deservirea clientului. Atat pe partea de client cat si pe partea de server se utilizeaza cate un obiect de tip Socket pentru comunicare. Pe partea de server mai trebuie sa cream un obiect de tip ServerSocket, care are sarcina primirii conexiunilor si acceptarea acestora.

Clientul trebuie sa cunoasca doua lucruri despre server: numele serverului (utilizat pentru determinarea adresei IP a serverului) si numarul portului la care acesta asculta cererile clientilor. Acelasi calculator gazda poate oferi mai multe servicii, deci poate gazdui mai multe procese de tip server. De exemplu poate fi server Mail, server FTP, server HTTP, dar aceste aplicatii lucreaza cu diferite porturi, deci cererile adresate acestor serveri vor fi receptionate pe diferite porturi. Privind modalitatea de deservire a clientilor serverul poate fi server paralel (concurent) si server secvential.

Serverul concurent permite deservirea in paralel a mai multor clienti. Acest paralelism se poate realiza prin crearea a mai multor procese fiu, cate unul pentru fiecare client sau prin crearea de fire de executie pentru deservirea fiecarui client. In Java vom utiliza cea de a doua modalitate. De obicei utilizam server cu arhitectura paralela pentru servicii la care deservirea unui client dureaza in timp. In general o aplicatie server trebuie sa execute urmatorii pasi:
1. Serverul aloca clienti 2. Cat timp ( mai { stabilire deservire eliberare } un port de comunicare care va fi cunoscut de catre sunt clienti la port ) conexiune cu client ( creare soclu ) client ( flux de intrare, flux de iesire ) conexiune ( eliberare soclu )

O aplicatie client executa urmatoarele:


1. Aloca un port de comunicare 2. Se conecteaza la server la portul cunoscut de dinainte 3. Se stabileste o conexiune prin care se trimit si se citesc date (soclu + fluxuri)

Clasa Socket
Constructori:
Socket(InetAddress address, int port)

Creaza un soclu si se conecteaza la adresa IP specificata prin obiectul InetAddress si portul specificat prin parametrul port.

Socket(InetAddress address, int port, InetAddress localAddr, int localPort)

Creaza un soclu si se conecteaza la adresa IP specificat prin obiectul InetAddress si portul specificat prin parametrul port. Ultimii doi parametri reprezinta adresa clientului si portul pe care acesta comunica .
Socket(String host, int port)

Creaza un soclu si se conecteaza la calculatorul host pe portul specificat prin parametrul port.
Socket(String host, int port, InetAddress localAddr, int localPort)

Creaza un soclu si se conecteaza la calculatorul host pe portul specificat prin parametrul port. Ultimii doi parametri reprezinta adresa clientului si portul pe care acesta comunica Metode principale:
void close()

Inchide soclul.
InetAddress getInetAddress()

Returneaza adresa la care soclul este conectat


InputStream getInputStream()

Returneaza un stream de intrare pentru soclu.


InetAddress getLocalAddress() int getLocalPort()

Returneaza adresa pe care soclul este creat. Returneaza numarul portului local.

OutputStream
int getPort()

getOutputStream()

Returneza un stream de iesire pentru soclu. Returneaza portul la care soclul este conectat.

Clasa ServerSocket
Constructori:
ServerSocket(int port)

Creaza un soclu server pe portul specificat.


ServerSocket(int port, int backlog)

Creaza un soclu server pe portul specificat. Al doilea parametru indica lungimea cozii de asteptare. Metode principale:

Socket accept()

Asculta conexiunile si le accepta.


void close()

Inchide soclul.
InetAddress getInetAddress()

Returneaza adresa locala al soclului server.


int getLocalPort()

Returneaza portul la care serverul asteapta conexiunile.

Exemplul 1.
Urmatoarea aplicatie este formata dintr-o parte client si una server. Clientul va trimite un sir de caractere serverului, iar serverul il va trimite inapoi convertit in majuscule. Pentru rezolvarea acestei probleme construim doua pachete:

Incepenm cu descrierea serverului. Serverul are o structura paralela, permite deservirea a mai multor clienti. Pentru fiecare client se va crea un obiect de tip ClientHandle, un obiect care ruleaza intr-un fir de executie separat si realizeaza deservirea clientului.

package ServerPackage; public class Server { public static void main(String[] args) { int port; if( args.length <1 ) { System.out.println( "Usage Server <portnumber>"); System.exit( 1 ); } try{ port = Integer.parseInt( args[ 0 ] ); } catch( NumberFormatException e ) { port = 1024; } try{ java.net.ServerSocket ss = new java.net.ServerSocket( port ); while( true ) ( new ClientHandle( ss.accept() )).start(); } catch( java.io.IOException e ) { System.out.println( "Server error ");

} }

package ServerPackage; import java.net.Socket; import java.net.SocketException; public class ClientHandle extends Thread { Socket client; public ClientHandle(Socket client) throws SocketException { this.client = client; } public void run() { try{ java.io.InputStream in = client.getInputStream(); java.io.OutputStream out = client.getOutputStream(); java.io.BufferedReader myin = new java.io.BufferedReader( new java.io.InputStreamReader( in)); java.io.PrintWriter myout = new java.io.PrintWriter( new java.io.OutputStreamWriter( out )); String request = myin.readLine(); System.out.println( "Request: "+request); myout.println( request.toUpperCase()); myout.flush(); myin.close(); myout.close(); client.close(); } catch( java.io.IOException e ) { System.out.println("I/O error "+e ); } } }

Partea de client:

package ClientPackage; public class Client { private String hostname; private int hostport; private String message; public Client(String hostname, int hostport, String message) { this.hostname = hostname; this.hostport = hostport; this.message = message; doIt(); } public void doIt() { try{ java.net.Socket s = new java.net.Socket( hostname, hostport ); java.io.BufferedReader in = new java.io.BufferedReader( new java.io.InputStreamReader(s.getInputStream())); java.io.PrintWriter out = new java.io.PrintWriter( s.getOutputStream() ); out.println( message ); out.flush(); System.out.println("Answer from the server: "+in.readLine() ); s.close(); } catch( java.io.IOException e ) { System.out.println( "I/O error "+e ); } }

public static void main(String[] args) { String hostname, message; int hostport; if( args.length < 3 ) { System.out.println("Usage Client <hostname> <hostport> <message>"); System.exit( 1 ); } hostname = args[ 0 ]; message = args[ 2 ]; try{ hostport =Integer.parseInt( args[ 1 ] ); } catch( NumberFormatException e ) { hostport = 1024; } Client c = new Client( hostname, hostport, message ); } }

Exemplul 2
Urmatoarea aplicatie va fi un server web. Aplicatia va rula pe un fir de executie cu prioritatea mai mica decat cea normala si va rezolva cererile HTTP. Vom proiecta aplicatia a.i. sa aiba o arhitectura paralela si sa rezolve cererile de tip GET nume_fisier.Arhitectura paralela permite deservirea concomitenta a mai multor clienti.
import java.io.*; import java.net.*; import java.util.*; public class TinyHttpd{ public static void main ( String args[] ) throws IOException { ServerSocket ss = new ServerSocket( Integer.parseInt( args[0])); while( true ) { Socket s = ss.accept(); TinyHttpdConnection t = new TinyHttpdConnection( s ); t.start(); } } }

class TinyHttpdConnection extends Thread{ Socket client;

TinyHttpdConnection ( Socket client) throws SocketException{ this.client = client; setPriority(NORM_PRIORITY -1); } public void run(){ try{ BufferedReader in = new BufferedReader( new InputStreamReader(client.getInputStream(),"8859_1")); OutputStream out = client.getOutputStream(); PrintWriter pout = new PrintWriter( new OutputStreamWriter(out,"8859_1"),true); String request = in.readLine(); System.out.println("Request: "+request); StringTokenizer st = new StringTokenizer( request ); if( (st.countTokens()>=2) && st.nextToken().equals("GET")) { if( (request = st.nextToken()).startsWith("/")) request=request.substring( 1 ); if( request.endsWith("/") || request.equals("")) request=request+"index.html"; try{ FileInputStream fis = new FileInputStream( request ); byte[] data = new byte[ fis.available()]; fis.read(data); out.write(data); out.flush(); } catch( FileNotFoundException e ){ pout.println(e.toString()); } } else{ pout.println("400 Bad request"); } client.close(); } catch( IOException e ) { System.out.println(e.toString()); } } }

Utilizarea aplicatiei: Aplicatia de mai sus se utilizeaza in modul urmator. Prima data se compileaza si dupa aceea se executa cu comanda:

java TinyHttpd 1234.


Numarul 1234 reprezinta portul la care serverul asteapta cererile. Dupa ce serverul este lansat in executie, dintr-un program de navigare (browser) se formuleaza o cerere de

forma: http://127.0.0.1:1234/Index.html, daca exista in catalogul aplicatiei TyniHttpd fisierul Index.html si daca clientul si serverul ruleaza pe acelasi calculator. 127.0.0.1 este adresa IP a localhost-ului. Daca aplicatia ruleaza pe un calculator cu numele unu.doi.com atunci in locul adresei 127.0.0.1 se pune unu.doi.com. Descrierea aplicatiei: Aplicatia defineste doua clase. O clasa care rezolva o cerere pe un fir de executie, TinyHttpdConnection si o clasa TinyHttpd care creaza soclul server si intra in asteptarea clientilor. In momentul aparitiei unui client ( accept()) se creaza un nou fir de executie caruia i se transmite referinta la soclul returnat de catre accept(). Aceasta referinta la soclu permite firului de executie sa extraga de aici fluxurile de intrare si de iesire prin care se realizeaza comunicarea efectiva. Firul de executie extrage din flux cu ajurorul unor operatii pe siruri de caractere, numele fisierului cerut. Daca exista fisierul, acesta se deschide pentru citire si datele citite vor fi scrise in soclu pentru a putea fi extrase si de catre client.

3. Modelul de comunicatie neorientat pe conexiune. Clasele DatagaramSocket si DatagramPacket


Trimiterea unei datagrame este similara cu trimiterea unei scrisori prin serviciul postal. In cazul trimiterii unei scrisori avem nevoie de un plic pe care scriem adresa destinatarului si dupa aceea punem scrisoarea in plic si o aruncam intr-o cutie postala. Analog la trimiterea unei datagrame trebuie sa cunoasten adresa si portul calculatorului caruia ii este adresata datagrama, dupa care putem sa punem datele in datagrama si sa le trimitem. Datagramele utilizeaza la nivelul transportului protocolul UDP. Acest protocol este unul nesigur, neorientat pe conexiune. Nu se face confirmare in cazul receptionarii acestor datagrame. Nici calea urmata de aceste datagrame nu se cunoaste dinainte. De aceea daca trimitem la acelasi destinatar mai multe datagrame, una dupa alta, nu putem fi siguri nici de ordinea primirii acestor datagrame. Din cauza ca protocolul nu necesita confirmarea sosirii datagramelor este un protocol rapid si se utilizeaza in cazul serviciilor unde nu este nici o nenorocire daca se pierde un pachet-doua (DNS utilizeaza UDP).

Descrierea claselor principale:


Clasa DatagramPacket:

Constructori:
DatagramPacket(byte[] buf, int length)

Construieste un obiect de tip DatagramPacket pentru primirea unui pachet de lungime length

DatagramPacket(byte[] buf, int length, InetAddress address, int port)

Construieste un obiect de tip DatagramPacket pentru trimiterea unui pachet de lungime length pe un port specificat, la un host specificat
DatagramPacket(byte[] buf, int offset, int length)

Construieste un obiect de tip DatagramPacket pentru primirea unui pachet de lungime length, specificand un offset in buffer
DatagramPacket(byte[] buf, int offset, int length, InetAddress address, int port)

Construieste un obiect de tip DatagramPacket pentru trimiterea unui pachet de lungime length pe un port specificat, la un host specificat, specificand si un offset

Metode:
InetAddress getAddress()

Returneaza adresa IP al calculatorului de la care se primiste sau la care se trimite datagrama


byte[] getData()

Returneaza sirul de octeti care se trimite sau care se primeste


int getLength() int getOffset()

Returneaza lungimea datelor care se trimit sau care se primesc Returneaza offsetul datelor care se trimit sau care se primesc
int getPort()

Returneaza numarul portului calculatorului la distanta la care se trimit datele sau de la care se primesc datele
void setAddress(InetAddress iaddr)

Seteaza adresa.
void setData(byte[] buf)

Seteaza bufferul pentru pachet


void setData(byte[] buf, int offset, int length)

Seteaza bufferyl pentru pachet


void setLength(int length)

Seteaza lungimea pachetului.


void setPort(int iport)

Seteaza portul.. Clasa DatagramSocket Constructori:


DatagramSocket()

Construieste un soclu si se leaga la un port liber pe calculatorul local

.
DatagramSocket(int port)

Construieste un soclu si se leaga la portul specificat pe calculatorul local.


DatagramSocket(int port, InetAddress laddr)

Construieste un soclu si se leaga la adresa si portul specificat Metode:


void close()

Inchide soclul
void connect(InetAddress address, int port)

Conecteaza soclul la o adresa si port la distanta.


void disconnect()

Deconecteaza soclul.
InetAddrress getInetAddress()

Returneaza adresa la distanta la care este conectat soclul .


InetAddress getLocalAddress()

Returneaza adresa locala la care este conectat soclul


int getLocalPort()

Returneaza portul local la care este legat soclul


int getPort()

Returneaza portul la distanta la care este legat soclul


void receive(DatagramPacket p)

Primire de datagrama prin acest soclu.


void send(DatagramPacket p)

Trimitere de datagrama prin acest soclu .

Exemplu:

Exemplul urmator va fi format pe partea clientului dintr-un aplet, care instiinteaza aplicatia server ori de cate ori este pornit. Apletul se include intotdeauna intro pagina HTML si programul navigator este cel care incarca si ruleaza apletul. Astfel daca pagina HTML reprezinta un homepage vom putea contoriza numarul vizitatorilor la pagina respectiva. Aplicatia este formata dintr-o parte client si una server. Clientul este un aplet, iar serverul o aplicatie.

Partea de client:

package ClientPackage; import java.applet.Applet; public class MessageApplet extends Applet { private String myHost; private int myPort; public void init() { myHost = getCodeBase().getHost(); myPort = Integer.parseInt( getParameter("PORT")); } public void sendMessage(String message) { try{ byte data[] =message.getBytes(); java.net.InetAddress addr = java.net.InetAddress.getByName( myHost ); java.net.DatagramPacket packet = new java.net.DatagramPacket( data, data.length, addr, myPort ); java.net.DatagramSocket ds = new java.net.DatagramSocket(); ds.send( packet ); ds.close(); } catch( java.io.IOException e ){ System.out.println(e ); } }

public void start() { sendMessage("Pagina incarcata"); }

Fisierul HTML:
<applet HEIGHT=10 WIDTH=10 CODE=MessageApplet.class> <param NAME="PORT" VALUE="1234"></applet>

Apletul utilizeaza metodele getCodeBase() si getHost() pentru aflarea numelui host-ului care il gazduieste, iar numarul portului se citeste din fisierul HTML. Astfel vor fi initializate datele obiectului MessageApplet, myHost si myPort. Metodele start() ,stop() , init() sunt metode publice care vor fi utilizate de catre navigator. init() se apeleaza o singura data la incarcarea paginii, iar start() ori de cate ori se revine la pagina respectiva. Metoda init() initializeaza datele obiectului, iar start() si stop() apeleaza metoda sendMessage() pentru trimiterea datagramei. Prima data se creaza un obiect

InetAddress, care este incarcat cu adresa hostului, dupa care se va crea un obiect de tip DatagramPacket care va contine atat adresa cat si mesajul de trimis.
byte data[] =message.getBytes(); //conversie String --> sir de octeti InetAddress addr = InetAddress.getByName( myHost ); //obtinerea adresei IP al hostului DatagramPacket packet = new DatagramPacket( data, data.length, addr, myPort ); //crearea pachetului

Dupa ce avem pachetul gata pregatit pentru trimitere, mai trebuie sa cream un soclu prin care sa fie trimis si putem expedia pachetul cu metoda send(). Dupa expedierea pachetului se va inchide soclul.
DatagramSocket ds = new DatagramSocket(); //Crearea soclu ds.send( packet ); //Trimitere pachet ds. close(); //Inchidere soclu

Partea de server:

import java.net.*; import java.io.*;

public class AppletServer{ public static void main( String args[]) throws IOException{ DatagramSocket s = new DatagramSocket( Integer.parseInt(args[0])); while( true ){ byte data[] = new byte[1024]; DatagramPacket packet = new DatagramPacket( data,1024); s.receive( packet ); String message = new String( packet.getData()); System.out.println("Hostname: "+packet.getAddress().getHostName()+" "+message); } } }

Partea de server:

package ServerPackage; public class AppletServer { public static void main(String[] args) { try { java.net.DatagramSocket s = new java.net.DatagramSocket( Integer.parseInt(args[0])); while( true ){ //Serverul se pregateste pentru primirea unui pachet byte data[] = new byte[1024]; java.net.DatagramPacket packet = new java.net.DatagramPacket( data,1024); //Serverul asteapta primirea unui pachet s.receive( packet ); //Se scot datele din pachet si se afiseaza la iesirea standard String message = new String( packet.getData()); System.out.println("Hostname: "+ packet.getAddress().getHostName()+" "+message); } } catch( java.io.IOException e ){} }

Aplicatia server creaza un soclu de tip DatagramSocket si intra in asteptarea clientilor pe un port. Numarul portului se primeste de la linia de comanda, fiind de tip String care se va converti la intreg prin apelul metodei Integer.parseInt(args[0]). Dupa crearea soclului se creaza un pachet gol pentru receptionarea datagramelor sosite. Acest pachet este un obiect de tip DatagramPacket care are si o variabila de tip sir de octeti, care se utilizeaza pentru stocarea datelor sosite, insa aceasta trebuie alocata inaintea sosirii datelor. Dupa ce s-au creat aceste doua obiecte, soclul apeleaza metoda receive() si intra in astepatarea datagramelor. In momentul sosirii unei datagrame, se extrage din aceasta mesajul si se va afisa pe terminal.

4. URL
URL (Uniform Resource Locator) identifica o resursa(obiect) pe Internet. In mod uzual este format din trei sau patru parti:
protocol://hostname/nume_resursa sau protocol://hostname:port/nume_resursa protocol:

poate fi http, ftp, gopher etc. hostname: numele calculatorului pe care se afla resursa, putem specifica si adresa IP, daca o stim in loc de nume host port: trebuie specificat doar daca serviciul este oferit pe un port nestandard. nume_resursa: calea si numele resursei Java ne ofera mai multi constructori pentru crearea unui obiect URL care pot genera exceptia MalformedURLException in caz ca lipseste ceva din specificatia URL. In momentul construirii obiectului nu se verifica existenta resursei, deci exceptia se genereaza daca un parametru este transmis incorect.
URL(String spec) URL(String protocol, String host, int port, String file) URL(String protocol, String host, String file)

Exemple de utilizare:
try{ URL url = new URL("http","www.uttgm.ro",3128, "index.html"); System.out.println( url.toString()); } catch( MalformedException e ){ //Se trateaza exceptia }

Un aplet poate comunica doar cu calculatorul pe care este stocat codul lui. Cu ajutorul metodei getDocumentBase() a clasei Applet putem afla numele acestui calculator si dupa acea putem cere accesul la o resursa de pe acel calculator:
try{ URL url = new URL("http",getDocumentBase(),"index.html"); System.out.println( url.toString());

} catch( MalformedException e ){ //Se trateaza exceptia }

Daca dorim sa aducem datele asociate unui URL trebuie sa cerem obiectului URL referinta la un stream atasat acestuia. Referinta se obtine prin apelul metodei openStream(). Exemplul urmator afiseaza pe terminal continutul unui fisier HTML.

try{

} catch (Exception e ){}

URL url = new URL("http://www.uttgm.ro/index.html"); BufferedReader bin = new BufferedReader( new InputStreamReader(url.openStream())); String line; while( ( line = bin.readLine()) != null ) System.out.println( line );

Exemplu cu URL: Sa se scrie un aplet care permite utilizatorilor vizualizarea produselor unei firme. Din cauza ca preturile sunt in continua schimbare acestea se stocheaza intr-un fisier "preturi.dat", aflat in acelasi catalog cu codul apletului, precum si cu fisierul HTML. In caz ca se schimba preturile produselor, apletul ramane neschimat, doar fisierul "preturi.dat" se va modifica. Cand clientul viziteaza pagina Web, browserul incarca prima data fisierul HTML, pe urma codul apletului. Apletul este rulat pe calculatorul clientului, acesta incarcand fisierul "preturi.dat". Pentru a incarca fisierul "preturi.dat", apletul creaza un URL:
try{ URL url = new URL( getDocumentBase(),"preturi.dat"); } catch( Exception e ){}

Lista de preturi este formatata a.i sa poata fi incarcata intr-un obiect Properties:
Mere=7000 Pere=10000 Struguri=25000 Basnana=27000

Incarcarea fisierului intr-un obiect Properties se va realiza prin:


Properties preturi = new Properties(); try{ preturi.load( url.openStream()); } catch( Exception e ){}

Interfata apletului:

Diagrama de clase:

Diagrama de secventiere:

Codul sursa: public class Linie_de_comanda { private String nume; private int cantitate; private double pretunitar; public Linie_de_comanda(String nume, int cantitate, double pretunitar) { this.nume= nume; this.cantitate = cantitate; this.pretunitar = pretunitar; } public String toString() { String s2 = Integer.toString( cantitate ); String s3 = Double.toString( pretunitar ); return nume+" : "+s2+" : "+s3; } }

import java.awt.Canvas; import java.util.Vector; import java.awt.Graphics; public class CanvasComanda extends Canvas { private Vector a; public void redraw(java.util.Vector a) { this.a =a; repaint(); } public void paint(Graphics g) { int i; int x=80, y=0; java.awt.Font f = new java.awt.Font("Monospaced",java.awt.Font.PLAIN, 12 ); g.setFont( f ); java.awt.FontMetrics fm = g.getFontMetrics( f ); int height = fm.getHeight(); y+=height; g.drawString("Your order: ",x,y); for( i = 0; i<a.size(); i++ ) { y+=height; g.drawString( a.elementAt(i).toString(), x, y ); } } } import import import import import import import import java.applet.Applet; java.awt.event.ActionListener; java.awt.Choice; java.awt.TextField; java.awt.Button; java.util.Properties; java.util.Vector; java.awt.event.ActionEvent;

public class ApletComanda extends Applet implements ActionListener { private Vector a = new java.util.Vector(); public CanvasComanda comanda; public Choice nume; public TextField cantitate; public Button adaugare; public Button gata; public Properties preturi; public void init() { setLayout( new java.awt.BorderLayout() );

java.awt.Panel p = new java.awt.Panel(); p.setLayout( new java.awt.FlowLayout()); nume = new Choice(); preturi = new java.util.Properties(); try{ java.net.URL url= new java.net.URL( getDocumentBase(),"preturi.dat"); preturi.load( url.openStream()); } catch( Exception e ){} java.util.Enumeration e = preturi.propertyNames(); while( e.hasMoreElements()) nume.addItem( ( String ) e.nextElement()); p.add( nume ); cantitate = new TextField( 5); p.add( cantitate ); adaugare = new Button("Adaugare"); p.add( adaugare ); adaugare.addActionListener( this ); gata = new Button( "Gata"); p.add(gata ); gata.addActionListener( this ); add( p, "North"); comanda = new CanvasComanda(); add( comanda,"Center"); comanda.setSize(250,150); comanda.redraw( a );

public void actionPerformed(ActionEvent arg0) { String command = arg0.getActionCommand(); if( command.equals("Adaugare")){ String itemName = nume.getSelectedItem(); int cant = 0; double pret = 0.0; try{ cant = Integer.parseInt( cantitate.getText()); pret = (new Double( preturi.getProperty( itemName ))).doubleValue(); } catch( NumberFormatException e ){} a.addElement( new Linie_de_comanda(itemName, cant, pret )); comanda.redraw( a ); } } }

S-ar putea să vă placă și