Cuprins
1. Introducere .....................................................................................................
1.1. Modelul client - server ......................................................................................................... 1.2. URL. Scheme URL ................................................................................................................. 1.3. Hipertext, hiperlegătură, hipermedia ............................................................................. 1.4. Protocolul HTTP (Hypertext Transfer Protocol) ..........................................................

2. FTP şi poşta electronică ...............................................................................
2.1. Serviciul FTP – transfer de fişiere .................................................................................. 2.1.1. Server FTP ................................................................................................................ 2.1.2. Client FTP ................................................................................................................. 2.2. Serviciul de poştă electronică – e-mail ........................................................................... 2.3. Exerciţii ..................................................................................................................................

3. Servere WEB ..................................................................................................
3.1. Introducere ............................................................................................................................ 3.2. IIS ........................................................................................................................................... 3.3. Exerciţii IIS ......................................................................................................................... 3.4. NCSA ....................................................................................................................................... 3.5. Apache .................................................................................................................................... 3.6. Exerciţii NCSA, Apache .....................................................................................................

4. Utilitare TCP - IP ..........................................................................................
4.1. Utilitare TCP - IP .................................................................................................................. 4.2. Testarea unei configuraţii TCP - IP ................................................................................. 4.3. Exemple de folosire a unor utilitare TCP - IP ...............................................................

5. Adresare IP ....................................................................................................
5.1. Clase de adrese ..................................................................................................................... 5.2. Exerciţii rezolvate ...............................................................................................................

6. Comunicare client – server la nivel de socket .........................................
6.1. Introducere ............................................................................................................................ 6.2. Interfaţa socket .................................................................................................................. 6.2.1. Comunicaţie client – server TCP - IP ................................................................. 6.2.2. Comunicaţie client – server UDP - IP ................................................................ 6.3. Exemplificări .........................................................................................................................

4 5 6 8 9 10 10 10 11 12 18 19 19 19 21 22 26 27 30 30 33 34 35 35 39 43 43 44 48 52 53 65 68 68 71 81 81

7. Implementarea aplicaţiilor distribuite pe platformele .NET şi J2EE ......................................................................................................................
7.1. Nivelul de acces la date ....................................................................................................... 7.1.1. Apelarea procedurilor stocate pe SQL Server ............................................... 7.1.2. Vizualizarea accesului la baza de date .............................................................. 7.2. Nivelul logicii aplicaţiei ....................................................................................................... 7.2.1. Apelarea procedurilor la distanţă .......................................................................

7.2.2. Serializarea tipurilor de date complexe .......................................................... 7.2.3. Apelarea serviciilor WEB în mod asincron ....................................................... 7.2.4. Publicarea unei componente ca serviciu WEB ................................................. 7.2.5. Servicii WEB virtuale ............................................................................................ 7.2.6. Autentificarea şi autorizarea accesului ........................................................... 7.3. Nivelul de prezentare .......................................................................................................... 7.3.1. Construirea unei imagini într-o pagină ASP.NET ............................................. 7.3.2. Apelarea unei componente dintr-un servlet .................................................... 7.3.3. Definirea unui Custom Tag în JSP ..................................................................... 7.4. Interoperabilitatea platformelor .NET şi J2EE ..........................................................

Bibliografie ..........................................................................................................

86 90 94 99 103 105 105 107 110 113 116

1 Introducere
Reţelele de calculatoare s-au dezvoltat spectaculos în ultimii ani, datorită evoluţiei tehnologiilor hardware, software şi de interconectare. Tehnologii de mare viteză au dus la utilizarea reţelelor de calculatoare în toate domeniile vieţii socio-economice, cu rezultate deosebite. Clasificarea reţelelor de calculatoare, după criteriul distanţei, în LAN (Local Area Network), MAN (Metropplitan Area Nerwork) şi WAN (Wide Area Network) este foarte cunoscută astăzi, iar Internet-ul este accesibil aproape oricui. Extinderea utilizării Internet-ului a dus la dezvoltarea serviciilor şi aplicaţiilor distribuite, prezentate pe scurt în acest material. Serviciile Internet cele mai răspândite sunt: WWW, poşta electronică (e-mail), transferul fişierelor (ftp), conectarea la distanţă (telnet, ssh). Unul dintre cele mai folosite servicii Internet este serviciul Web. WWW (World Wide Web), cunoscut şi sub denumitrea de Web sau W3, reprezintă serviciul Internet care permite navigarea pe colecţii de documente multimedia (hypertexte), din diferite reţele, calculatoare prin hyperlegături, utilizând o interfaţă comună (browser-ul). Caracteristici: Se deosebeşte de alte servicii Internet deoarece, prin concepţia sa, înglobează alte servicii ca: FTP, Gopher, Telnet, News. Reprezintă subnivelul superior al nivelului aplicaţie. Face apel la următoarele elemente: o URL (Universal Resource Locators) identificatorul uniform al resurselor; o HTTP (HyperText Transfer Protocol); o HTML (HyperText Markup Languages). Serviciul Web se deosebeşte de alte servicii Internet prin faptul că înglobează unele dintre ele, cum ar fi FTP, Gopher, Telnet, Wais, News. 4

Reţele de calculatoare

1.1 Modelul client-server Cel mai răspândit model de comunicare în Internet, având la bază protocolul TCP/IP, este modelul client-server, model după care funcţionează toate aplicaţiile şi serviciile Internet. Clientul, de obicei, rulează pe calculatorul utilizatorului şi este folosit pentru a accesa informaţii sau alte aplicaţii din cadrul reţelei. Browser-ul: emite cererile şi recepţionează datele care vor fi afişate; formatează documentele ţinând cont de tag-urile HTML; afişează documentele. Exemple: Netscape, Internet Explorer, Lynx, HotJava, Mosaic. Serverul rulează, de obicei, pe un calculator centralizator sau aflat la distanţă, furnizând sau oferind informaţii/servicii clienţilor. Exemple: Apache, NCSA, IIS (daemon httpd).
Client (cerere/răspuns) Server

Figura 1.1 Modelul client-server Modelul client-server are la bază un protocol simplu, fără conexiune de tipul întrebare-răspuns. La implementarea modelului client-server se ţine seama de: adresarea proceselor server; tipul primitivelor utilizate în transferul mesajelor (sincrone/asincrone, cu/fără tampon, fiabile/nefiabile). Clientul şi serverul se pot găsi în acelaşi nod, când se utilizează mecanisme de comunicaţie locală sau în moduri diferite, când se utilizează mecanisme de comunicaţie în reţea. 5

Introducere

1.2 URL. Scheme URL Generalităţi: S-a pus problema unui sistem standardizat de regăsire uniformă a resurselor. Pentru a se putea referi în mod standard, în cadrul aplicaţiei Web, orice tip de document (text, imagine, sunet), a fost creată specificaţia URL (Uniform Resource Locator). Prin URL se înţelege o descriere completă a unui articol, ce conţine localizarea acestuia, articolul putând fi un fişier de pe maşina locală, sau altul din orice parte a Internet-ului. Suportul principal pentru URL îl reprezintă documentul de tip hipertext. Acest document conţine link-uri (legături la alte servere) normalizate de tip URL. Hipertextul se descrie printr-un limbaj foarte simplu, care se poate implementa în orice fişier ASCII, numit html. Sintaxa generală Un URL complet constă într-o schemă, urmată de un şir de caractere cu format special, care este o funcţie a respectivei scheme. [URL:] schema-de-denumire | sir URL-ul cuprinde trei părţi: un cod pentru a identifica protocolul de transfer ce va fi utilizat; adresa pentru a identifica host-ul pe care sunt stocate fişierele; un descriptor de cale pentru amplasarea punctului (locaţiei) pe acea maşină. URL-ul trebuie să înceapă cu numele schemei, urmat de “:”, apoi adresa locaţiei unde se găseşte resursa, încadrată între caracterele: “//” şi “/” şi opţional un nume de utilizator şi o parolă.

6

1 PROTOCOL DESCRIERE MOD DE LUCRU HTTP Protocol de transfer http://host[:port][/cale][?cautare] hipertexte FTP Protocol de transfer de ftp://[user[:parola]@]host/cale fişiere MAILTO Adresa de E-mail mailto:user@host NEWS Ştiri Usenet news:grup-discutii NNTP Ştiri Usenet pentru acces nntp:grup/cifre local NNTP FILE Acces la fişiere file://host/cale TELNET Referire la o sesiune telnet://host[:port] interactivă Tipuri de URL–uri: relative . atunci înseamnă că avem de-a face cu un utilizator anonimous. Scheme URL standard Tabelul 1. 7 .1. Conform cu definiţia BNF a sintaxei. există câteva scheme URL standard. care vor fi prezentate în tabelul 1. Termeni UR*: URI – Universal Resource Identifier este numele pentru identificatorul generic WWW. Specificaţiile URI definesc sintaxa pentru codificarea arbitrară a schemelor şi conţin o listă a acestor scheme.exp: „doc/document_html”.Reţele de calculatoare Pentru protocoalele Internet avem următoarea formă generală: schema://[ [nume-utilizator] [:parola]@ ] nume-de-domeniu-Internet [:număr-port] [/lista-de-directori] [/nume-de-fisier] Dacă nu se specifică numele de utilizator şi parola corespunzătoare. absolute .exp: „met_acces://nume_server[:port]/cale/”.

animaţie şi sunete. URL-ul în forma sa absolută conţine un tip de informaţie care este deja cunoscută de serverul destinaţie. tipul de dată. data calendaristică. facilitând astfel transferul fişierelor.3 Hipertext.Introducere URL – Uniform Resource Locator este o reprezentare compactă a locaţiei şi a metodei de acces pentru resursele disponibile pe Internet. Un singur click cu mouse-ul pe fiecare frază superluminată şi browser-ul va urmări automat acea legătură şi va afişa pe ecran o nouă informaţie. 8 . Multe alte documente din Web sunt hipermedia. în timp ce alte legături îl pot purta în oricare punct din cadrul oricărui alt document din cadrul Web-ului. nefiind un URL în adevăratul sens al cuvântului. O hiperlegătură leagă textul curent cu altă informaţie aflată undeva în Internet sau cu o nouă locaţie din cadrul documentului curent. URN – Uniform Resource Name este o schemă particulară care include autenticitate. În prezent. Umărind un anumit set de legături. cititorul poate naviga înainte sau înapoi în cadrul unui singur document. hipermedia Hipertext este un text ce conţine legături numite hiperlegături sau ancore. Hiperlegăturile sunt evidenţiate în cadrul browser-ului în mod grafic cu o culoare şi/sau subliniate. hiperlegătură. Când este conţinut într-un document de bază. cum ar fi: autorul. elemente de copyright şi dimensiunea documentului. cititorul se poate deplasa în interiorul unui document sau de la un document la altul. 1. conţinând imagini şi legături cu grafice. Urmărind aceste legături. publicistul. Trebuie specificat că nu este necesară citirea linie cu linie a acestui hipertext. URC – Uniform Resource Characteristics reprezintă un set de atribute care descriu un obiect. reproducere şi disponibilitate pentru URL-uri. către alte texte sau informaţii. termenul hipertext semnifică doar textul de bază al documentului.

orientat obiect. Este un protocol de nivel aplicaţie. care garantează că datele au fost recepţionate corect. care poate fi folosit cu uşurinţă de multe task-uri. Este un protocol generic. Este un protocol rapid. special proiectat pentru mediul interactiv. datele pot circula în ambele direcţii simultan. prin mecanismul de fereastră glisantă. duplicate sau recepţionate în altă ordine faţă de cea în care au fost transmise. nu au fost pierdute. cu extensiile cerute de metodele sale. Circuitul virtual este full-duplex. construirea de sisteme independente de date care vor fi transferate. modulul HTTP al calculatoruluiclient şi modulul HTTP al calculatorului-server încep să comunice unul cu altul. Când se startează o aplicaţie. Este construit peste serviciile protocolului TCP/IP.Reţele de calculatoare 1. Aceste două module (client şi server) conţin informaţii de stare care definesc un circuit virtual. 9 . Procesul de recepţie are controlul asupra vitezei la care se recepţionează şi se transmit datele. ce oferă uşurinţa şi viteza necesare dezvoltării aplicaţiilor hipermedia. Este orientat pe conexiune şi asigură recepţionarea sigură a pachetelor de date. cât şi ale clientului. oferind şi o metodă de control al fluxului între hosturile sursă şi destinaţie. hipermedia din Web. Permite tipărirea şi negocierea reprezentării datelor. cum ar fi servere de nume şi sisteme de management distribuit. Acest circuit virtual consumă resursele atât ale serverului.4 Protocolul HTTP (Hypertext Transfer Protocol) Caracteristici: Este cel mai important şi cel mai des folosit protocol al Reţelei Mondiale (Web).

folosind SSL . numit anonymous (sau ftp).Secure Sockets Layer).2 FTP şi poşta electronică 2. Parola este transmisă în clar prin reţea. astfel încât transferul să se realizeze prin canale sigure (de exemplu. transferul de informaţii prin FTP se va efectua doar în zone în care se ştie că nu este posibilă monitorizarea reţelelor de către orice utilizator. care nu este protejat prin parolă şi pentru care majoritatea serverelor moderne cer introducerea ca parolă a adresei de poştă electronică a utilizatorului client. Protocolul este FTP (File Transfer Protocol) şi este specificat în RFC 454. Funcţionează pe modelul client-server. permiţând oricărui utilizator local care are acces la un program de monitorizare a reţelei să o afle. sau cele care oferă FTP anonim.1. Este bazat pe un sistem de autentificare a utilizatorilor.1 Serviciul FTP . În mod normal.1 Server FTP Caracteristici: Importanţa serviciului FTP este indicată şi de faptul că toate sistemele Unix sunt instalate cu un set de programe client şi server. Browserele cunosc nativ şi protocolul FTP (schema URL este: ftp://[cont@]server. 2. Există un cont special. un utilizator trebuie să deţină un nume de cont şi o parolă validă pentru respectivul server. Din acest motiv. Există servere publice. pentru accesul la documentele de pe un server FTP. O altă posibilitate este folosirea de clienţi sau servere modificate.domeniu/ ).Transfer de fişiere Caracteristici: Permite transferul fişierelor de orice tip (fie ele binare sau de tip text) între două calculatoare din Internet. 10 .

FTP trebuie instalat explicit. În fişierul /etc/services trebuie să existe următoarele linii: ftp ftp-data 21/tcp.ro/cale_HOME/ 11 . Trebuie verificat dacă există în fişierul /etc/services o intrare care să facă asocierea dintre numele simbolic ftp şi 21.de al prompt-ul DOS.de pe care serverul iniţiază conexiunea pe care se va face transferul de informaţie. fie ca serviciu de reţea. fie ca parte a server-ului Web (IIS . spre deosebire de situaţia clasică.pe care se transmit comenzile de la client la server.ase. existând variante care integrează perfect clientul FTP cu Windows Explorer). folosind schema URL: ftp://user@infocib. numărul de port TCP cu care este asociat acest serviciu. tasta upload al browser-ului Internet Explorer. Clientul – pe staţia utilizatorului.Reţele de calculatoare Utilizează 2 porturi: portul 21 . Macromedia Dreamweaver) la cele de aplicaţii de birotică (Microsoft Office. Programele "ascund" comenzile clientului ftp din linia de comandă. majoritatea punând accent sporit pe transferul informaţiilor de la client la server.conf) conţine o linie de forma: ftp stream ftpd tcp nowait root /usr/sbin/ftpd În sistemele Windows. portul 20 .Internet Information Server).2 Client FTP Suita programelor care includ clienţi FTP variază de la cele care dezvoltă şi administrează servere WWW (Microsoft FrontPage. 2. un program sub SO Windows (exp: WinFTP). poate fi: comanda ftp . în care transferul majoritar era de la server la client. administratorul trebuie să se asigure că fişierul de configurare a programului inetd (/etc/inetd. Când serviciul FTP este pornit de către super-serverul inetd.1. 20/tcp.

Principalele componente sunt: 1.ro .multiple get >quit – închidere sesiune 2. se recomandă pentru fişiere ZIP.2 Serviciul de poştă electronică – e-mail Cunoscut şi sub denumirea de e-mail (electronic mail).ase.User Agent). >hash – vizualizarea transferului fiecărui 2048 B >cd director_server – schimbă directorul din home directory-ul user-ului >put fis. imagini etc. acolo unde se găsesc fişierele voastra/ sau unde doriţi să le puneţi pe cele aduse >bin – trecerea modului de transfer din ASCII în binar.ext – multiple put – pune toate fişierele cu extensia . în directorul din home-ul utilizatorului >mput *. datorită caracteristicii sale de a permite trimiterea de documente electronice între utilizatorii conectaţi la reţea. locul în care ajunge poşta electronică şi din care agentul utilizator preia poşta. cerând confirmare la fiecare >get fis.ext – pune fişierul din directorul local curent pe server-ul infocib. Vom exemplifica modul din prompt MS-DOS: c:\>ftp >? vă arată toate subcomenzile ftp >o infocib. care este de obicei un program cu care utilizatorul îşi citeşte şi trimite poşta electronică. este cel care a stat la baza dezvoltării Internet-ului. EXE. în sensul că emiţătorul şi receptorul nu trebuie să fie simultan conectaţi pentru ca mesajul să ajungă de la sursă la destinaţie.deschide conexiunea cu server-ul de ftp de pe infocib user: contul_vostru password: parola_voastra >lcd c:\director_local – schimbă directorul de pe maşina locală. agentul utilizator (UA . 12 . serverul de poştă electronică (cutia poştală).ext – ia de pe server şi pune pe local >mget * .ext. Funcţionarea serviciului poate fi considerată asincronă. 2.FTP şi poşta electronică Există mai multe modalităţi de transfer.

Pentru a trimite scrisoarea unui destinatar. Clientul stabileşte o legătură TCP cu serverul şi îi trimite mesajul. IMAP Agent postal (MTA) SMTP Agent postal (MTA) Cutie postala pentru Andrei Agent postal (MTA) Cutie postala pentru Bogdan Figura 2. agenţii de transfer (MTA . transmiterea mesajelor dintr-un sistem în altul).1 Modul de transmisie a poştei electronice şi protocoalele utilizate în cadrul acestui sistem La terminarea compunerii unei scrisori. în conformitate cu protocolul SMTP (Simple Mail Transport Protocol). Andrei Agent Utilizator (UA) SMTP Bogdan Agent Utilizator (UA) Agent postal (MTA) POP. Serverul primeşte mesajul şi plasează copia scrisorii în cutia corespunzătoare destinatarului.Reţele de calculatoare 3. Poşta electronică are facilităţi importante de retransmitere a mesajelor către unul sau mai mulţi destinatari. Acesta aşteaptă ca în coada sa de intrare să fie plasată o scrisoare. Programul de transfer este optimizat să trateze împreună toţi recipienţii situaţi într-o aceeaşi maşină distantă. care preiau mesajele de la UA şi le retransmit prin reţea către cutia poştală a destinatarului. pe care o trimite tuturor destinatarilor. Pentru comunicarea între utilizatorii diferitelor sisteme de poştă electronică s-au introdus porţi de poştă electronică (realizează conversia între formatele de mesaje proprietare şi permit. agentul de transfer acţionează ca un client şi contactează serverul maşinii de la distanţă în care se află cutia poştală a destinatarului. agentul utilizator o plasează într-o coadă prelucrată de agentul de transfer. astfel. Programul care realizează retransmiterea 13 .Mail Transfer Agent).

copie la indigo) specifică. data expedierii. Mesajele de poştă electronică sunt compuse din trei părţi. numit poartă poştală (e-mail gateway). fără ca receptorii să cunoască acest lucru. de obicei.FTP şi poşta electronică foloseşte o bază de date. SMTP (Simple Mail Transport Protocol) – unul dintre cele mai importante protocoale de comunicaţie între MTA-uri. El este folosit atât pentru comunicarea între agenţii de transport al poştei. Atunci când se doreşte trimiterea mesajului către un destinatar. La sosirea unei scrisori. este acelaşi cu serverul care menţine cutiile poştale). Fiecare intrare în baza de date. Adresele de poştă electronică au formatul general utilizator@server_poştă. se poate folosi câmpul bcc: (blind carbon copy. Protocoale implicate în transferul poştei electronice pe Internet: 1. unde utilizator este numele de cont sau un pseudonim al destinatarului. publice. fiecare destinatar din cei menţionaţi în această listă urmând să primească o copie a mesajului. De aceea el este găzduit de un sistem care oferă aceste resurse. Programul de retransmitere consumă resurse importante (memorie şi timp). Câmpul cc: (de la carbon copy.). mesaj: cuprinde mesajul propriu-zis. definit în RFC 821. cele mai importante câmpuri ale antetului se referă la adresa destinatarului (sau ale destinatarilor). cât şi pentru transmisia mesajului de la agentul utilizator către serverul local de transmisie a poştei electronice (care. copie la indigo invizibilă). în mod uzual. primele două fiind descrise în cadrul RFC 822: antet: zonă care cuprinde informaţiile de control ale mesajului (adresele emiţătorului şi receptorilor. iar server_poştă este adresa staţiei care face serviciul de cutie poştală sau un nume de domeniu. fişiere ataşate: sunt de regulă binare şi însoţesc mesajul principal. numită listă poştală (mailing list) are propria sa adresă poştală şi conţine o mulţime de adrese. de asemenea. din care află cum trebuie să prelucreze mesajul. o listă de persoane care vor primi copii ale mesajului. Câmpul to: specifică o listă de adrese de poştă electronică. Dacă da. programul examinează adresa de destinaţie şi determină dacă aceasta corespunde unei liste poştale. traseul mesajului etc. 14 . Din punctul de vedere al utilizatorului. atunci programul retransmite o copie a mesajului către fiecare adresă din listă. Listele păstrate de porţile poştale sunt.

Această abordare este comodă pentru utilizatorii care nu au un punct fix de lucru. definit în RFC 1225. După reconectare. iar toată gestiunea mesajelor este menţinută pe server. Post Office Protocol. Sincronizarea între cele două cutii poştale nu este prevăzută explicit în cadrul protocolului şi este. după care se deconectează. Acesta permite ca agentul utilizator să lucreze cu copii temporare ale mesajelor. apoi legătura cu serverul POP3. Sistemul care păstrează cutia poştală găzduieşte două servere. POP3 foloseşte tot protocolul TCP. 4. scrisorile sunt retransferate şi sistemul este resincronizat. dar este diferit de acesta. IMAP (Interactive Mail Access Protocol) – definit în RFC 1064. iar modelul de lucru implementat este decuplat (off-line). clientul POP3 face identificarea utilizatorului (numeparolă). Acesta accesează cutia poştală a utilizatorului şi transmite clientului noile scrisori aflate aici. La apelul său. unul SMTP şi unul POP3. Versiunea sa cea mai utilizată se numeşte POP3 – permite descărcarea poştei de pe serverul central. fiind adaptată pentru reţele de tip Intranet. Serverul POP3 poate fi folosit şi cu conexiuni comutate (dial-up). presupune existenţa mai multor cutii poştale şi permite transferul scrisorilor către o staţie de lucru. ca şi SMTP. Clientul POP3 se execută pe PC-ul utilizatorului. Presupune existenţa a două cutii poştale. Se foloseşte pentru a se înlătura deficienţele constatate în POP3. una pentru recepţie (cea de pe server) şi una de lucru (cea gestionată de agentul utilizator).Reţele de calculatoare 2. Modul de gestiune folosit de produsele bazate pe IMAP este cuplat (on-line). Serverul POP3 lucrează pe maşina pe care se află cutia poştală. DMSP (Distributed Mail System Protocol) – definit în RFC 1056. ajuns la versiunea 4. 15 . imposibil de realizat o menţinere unitară a poştei electronice în cazul în care utilizatorul nu foloseşte întotdeauna acelaşi calculator pentru a-şi accesa poşta. 3. practic.

16 . în legătură cu sistemul de poştă electronică deoarece îi furnizează acestuia atât adrese. 2046. unde se utilizează programul mail pentru trimiterea mesajelor. care specifică transformarea unei secvenţe de 3 caractere pe 8 biţi într-o succesiune de 4 caractere care pot fi tipărite (litere. La sistemele Unix. iar la recepţie se va face uudecode. Tipul documentului ataşat este indicat în antetul mesajului de poştă electronică. folosindu-se codificarea bazată pe tipurile MIME. Cele binare trebuie trimise după ce li s-a aplicat uuencode. 2045. Documentele binare sunt codificate conform standardului BASE64. Serviciul de directoare este folosit. 2048 şi 2049. printr-un serviciu centralizat de directoare şi clienţi LDAP (atât Netscape. reprezentate pe 6 biţi. Pentru o transmisie corectă şi o identificare uşoară a tipului documentului ataşat. de la emiţător către destinatar. transferul se face conform standardului MIME. 2047.standard definit pe parcursul a mai multor documente RFC: 1521. Tipul documentului permite programelor de poştă electronică să lanseze în execuţie programul care ştie să vizualizeze documentul ataşat recepţionat. semne de punctuaţie). Transferul documentelor prin intermediul poştei electronice: Prin facilitatea de ataşare a documentelor la un mesaj de poştă electronică este posibilă transmiterea unui fişier binar. Se poate construi o agendă cu informaţii despre persoanele implicate în sistemul de poştă. cifre. Servicii de directoare: LDAP (Lightweight Directory Access Protocol) . în special.protocol uşor de acces la cataloage. cât şi Microsoft au adoptat LDAP).FTP şi poşta electronică Ambele protocoale au două mari deficienţe: autentificarea se face pe baza unei parole care circulă în clar prin reţea iar mesajele aduse de la server sunt transferate în clar. Caracteristici MIME: MIME (Multipurpose Internet Mail Extensions) . nu numai text. Implicit SMTP-ul permite transfer de documente ASCII. cât şi certificate necesare pentru criptarea şi semnarea mesajelor de poştă. fişerele se ataşează cu comanda ~r nume_fiş în corpul mesajulul.

Soluţia rezolvă ambele probleme ale sistemelor de poştă. înainte de începerea "discuţiei" dintre agentul utilizatorului şi cutia poştală. Din acest motiv. application. singurul client de poştă electronică folosit pe scară largă care este capabil să stabilească conexiuni SSL este Netscape Messenger. precum şi 7 tipuri (text. de tipul SSL (Secure Sockets Layer). tipurile documentelor sunt cunoscute şi sub numele de tipuri MIME.Fişier binar. atunci când accesează o cutie poştală de tip IMAP. există două variante: Criptarea canalului de comunicaţie – se face prin intermediul unui protocol sigur. Practic. image. Content-Tranfer-Encoding.) cu mai multe subtipuri. cu tip nespecificat. La ora actuală. Sistemul MIME a fost preluat şi de Web prin protocolul HTTP. Identificatorul de tip este definit ca fiind compus dintr-un tip şi un subtip. Dezvoltat iniţial pentru a permite introducerea în cadrul mesajelor de poştă electronică a unor noi tipuri de informaţii pe lângă cele clasice de tip text. se stabileşte un canal criptat pe care se va face atât autentificarea.Reţele de calculatoare Cel mai folosit mod de specificare a tipului de conţinut. Content-ID. Este o completare a RFC 822.1 Tip/subtip MIME text/plain Tipul informaţiei asociate Informaţie de tip text care nu necesită interpretări speciale text/html Document ce conţine o pagină HTML image/gif Document de tip imagine codificată conform standardului GIF image/jpeg Document de tip imagine codificată conform standardului JPEG application/octet. care trebuie tratat ca un stream şir de octeţi video/mpeg Film codificat conform standardului MPEG Pentru transferul mesajelor în siguranţă. Content-Description. Tipuri/subtipuri MIME Tabel 2. cât şi transferul mesajelor. message. introducând alte 5 antete de mesaje: MIME-version. 17 . cele două componente fiind separate printr-un slash. Content-Type. multiplart etc.

Studiaţi RFC-urile menţionate în seminar (pentru ftp.ase.3 Exerciţii 1. 6. e-mail. aceste soluţii nu au un sprijin important din partea producătorilor de servere de poştă electronică sau din partea producătorilor de clienţi. dar rezolvă atât problema transferului sigur al mesajului. SMTP. IMAP. Astfel. iar firma Microsoft a adus unele extensii protocolului POP3 (mecanismul SPA . Problema autentificării în siguranţă a utilizatorului cu cutia poştală poate fi rezolvată atât prin criptarea canalului de comunicaţie. 5. 18 . POP3. De exemplu. Verificaţi existenţa serverelor de ftp. apoi folosiţi un browser. MIME) 2. Din păcate. pop3 pe infocib (ps aux) şi portul pe care rulează (netstat –a) 3. soluţia de tip PGP poate fi implementată cu succes în medii Windows şi Unix.Secure POP Authentication) care au fost înglobate în clienţii de mail Outlook şi Outlook Express.ro. asigurând integrare cu toţi clienţii de poştă electronică. protocolul IMAP prezintă un mod opţional de criptare doar pe perioada autentificării. Recapitulaţi programul mail din Unix. Trimiteţi prin acest sistem (cu SMTP) un fişier binar (uuencode/ uudecode). IMAP. 2. Citiţi-vă poşta de pe infocib folosind un client de e-mail sub SO Windows (folosiţi POP3). folosind consola de management MMC (se lansează din Internet Service Manager) 4. cât şi prin extensiile aduse celor două protocoale care gestionează poşta electronică de la client.lasă deschisă problema autentificării cu cutia poştală. Creaţi-vă un cont de e-mail pe http://mailcom. cât şi pe cea a verificării identităţii emiţătorului. Porniţi şi testaţi serverul de ftp din PWS (Personal Web Server). e-mail. Citiţi-vă e-mail-ul folosind un client de e-mail configurat pentru POP3.FTP şi poşta electronică Criptarea mesajului .

PWS (Personal Information Server) – pentru Win. VMS.0. 3.pentru platforme Unix. Ajuns la versiunea 5. NCSA . Elemente de securitate: Restricţii IP şi de domenii Internet – se poate da/lua accesul la anumite pagini în funcţie de adresa IP sau de domeniul de la care se conectează utilizatorul.95/NT Workstation. XP. PWS – Personal Web Server – pentru Win 9x şi NT Workstation. IIS (Internet Information Server) – pentru WinNT Server. ca de exemplu: Apache . server public. Conţine instrumente de căutare şi facilităţi de autorizare a accesului. Conţine negocieri.pentru platforme Unix. disponibil cu Option Pack 4. disponibil cu Windows 2000 Server.pentru platforme Unix. fişiere log extinse. Există o mare varietate de servere Web pentru diferite forme de date.2 IIS Serverul de Web IIS (Internet Information Server) are următoarele caracteristici: Internet Information Server – server de Web pentru SO Windows NT Server. Windows 2000 Server Family. CERN .3 Servere Web 3.1 Introducere Un server WWW este un program care răspunde pe o conexiune TCP şi furnizează servicii unuia sau mai multor clienţi. Windows. 19 .

integritatea. limitarea % CPU pentru procesele ASP. ISAPI. care permite utilizarea de criptări pe 128 biţi. Fortezza – standard de securitate al guvernului USA. gestionarea se realizează prin componenta Windows Certificate Manager. autentificarea şi controlul mesajelor. IP acelaşi sau diferit) şi directoare virtuale (alias – utile când paginile pe Web se găsesc pe mai multe drive-uri ale calculatorului. Autentificare rezumat (digest authentification) permite autentificarea utilizatorilor prin servere proxy şi ziduri de protecţie. director sau fişier. Write. setări pentru drepturile de acces: Read. administrare la distanţă prin Web. fiecare site suportă şi un Operator. aplicaţii CGI. Administrare: crearea de servere virtuale (porturi diferite. Script la nivel de site.Servere Web Comunicaţii sigure – prin SSL (Secure Socket Layer) şi TSL (Transport Layer Security). administrare centralizată prin MMC (Microsoft Management Console) – include programe numite “snap-ins”. cu drepturi restrânse. Stocare de certificate de autentificare – integrat cu Windwos CryptoAPI. sunt reprezentate prin icoana cu glob într-un colţ). asigură confidenţialitatea. include autentificare Windows pentru accesul la paginile deWeb. SGC (Server-Gated Cryptography) – extensie a SSL. contorizarea proceselor pentru fiecare server de Web care rulează. componentelor şi sistemelor. Execute. Kerberos v5 – protocol de autentificare integrat în Win2000 care permite trecerea elementelor de autentificare printr-o reţea de calculatoare Windows. 20 .

High (Isolated) .3 Exerciţii IIS 1. Verificaţi existenţa IIS: port.exe). Verificaţi dacă există c:\Inetpub (directorul rădăcină al IIS). director. respectiv directoarele wwwroot.exe. aplicaţiile rulează într-o altă instanţă a DLLHost.exe (serverul ca serviciu) (CRTLALT-DEL -> Task Manager -> Processes) (Control Panel-> Services). Lansaţi pagina implicită a IIS (http://localhost/). Verificaţi dacă rulează InetInfo. 3. serviciu. 4. ftproot pentru serverele de web şi ftp. proces.Reţele de calculatoare protecţia aplicaţiilor – IIS oferă 3 niveluri: • • • Low (IIS Processes) – aplicaţiile rulează în acelaşi process ca şi serviciile Web (Inetinfo. 2.aplicaţiile rulează în procese diferite de serviciile Web (DLLHost. 3. 21 .implicit.exe) Medium (pooled) .

puneţi un fişier cu extensia .xbm. Daţi drept de browse.html. 7. CGI-BIN pentru fişier cgi. Din Sharing. 4.infocib. icons. 9. Caracteristici NCSA: Codul sursă al versiunii httpd_1. logs. LOGS pentru a se vedea logările/erorile de logare. 6. 22 . Vizualizaţi setările implicite ale serverului implicit IIS (home directory. Verificaţi site-ul.ase.html. dintre care ultimele trei conţin fişiere "makefile".0 compilat după aplicarea utilitarelor uncompress şi tar se obţin directoarele: 1. cgi-src.4 NCSA Crearea unui server http utilizarea un server deja existent. Utilizatorul trebuie să modifice anumiţi parametri doar din makefile-ul directorului src.gif şi .html în directorul setat ca root pentru documentele serverului. Modificati fişierul implicit de pornire în index.ro crearea propriul server: gata compilat sau sub formă de surse. de exemplu www. după care reîncărcaţi site-ul. Din consola de management. BIN cu fişierul httpd. creaţi un director virtual cu numele dumneavoastră în site-ul creat anterior şi daţi drept de browse pe acel director (în afară de cele implicite). în index. Refaceţi paşii cu fişierul default.3 are şapte directoare: cgi-bin. după care testaţi-l. 3.Servere Web 5. conf. 6. CONFIG cu patru fişiere de configurare. 8. support. 5. Lansaţi Computer Management. 11. Vizualizaţi porturile ocupate (netstat –a –n|more) 10. creaţi un alt director virtual în acelaşi site. Faceţi în aşa fel încât accesul să se realizeze pe bază de cont de Windows cu parolă. prin care se compilează produsul. src. ICONS cu fişiere de tip . apoi redenumiţi fişierul dvs. port. 2. 3. HTDOCS pentru fişierele de tip . Produsul httpd_3. Creaţi un site pe portul 8000 cu numele grupei.html (în consola de management). drepturi etc).

cum ar fi amplasarea documentelor şi a scripturilor CGI. sub forma în care este înregistrat. conf/srm.conf – fişierul de configurare al resurselor serverului. Redirect – creează un document virtual pe server. având de modificat variabile în /src/Makefile şi /src/config. ServerRoot – locaţia unde se găseşte daemon-ul. srm.conf. De exemplu www. şi pus pe "enable".ase. adică numele serverului WWW. UserDirectory – directorul ce specifică un subdirector pe care trebuie sa-l creeze utilizatorii pentru html-urile proprii. Port –indică portul pe care httpd-ul va asculta cererile clienţilor.conf.Reţele de calculatoare Se bazează pe CGI şi utilizează programe de criptare. DocumentRoot . Există trei tipuri de configurare a serverului: prin compilarea sursei httpd. exemplu: /usr/etc/httpd/htdocs.ro (orice server nou creat de forma www sau de altă formă trebuie să fie înregistrat pentru a putea fi utilizat şi de alţii). Alias – creează o legătură între un document/director virtual de pe serverul de Web şi un document/director de pe calculatorul server. configurare în timpul rulării.infocib. care este implicit. ScriptAlias – indică directoarele care sunt autorizate să includă script CGI. de exemplu: conf/access. ServerName – aliasul DNS. modificarea fişierelor de configurare cu parametri specifici sistemului.conf – fişierul de configurare al serverului – conţine informaţii referitoare la: ServerType – tipul serverului (stand-alone sau inetd).h (la versiunea de la NCSA). Principalele tipuri de fişiere şi directivele care trebuie configurate sunt: httpd. Pentru ca userii să poată scrie în acel director trebuie comutat de pe "disable". de exemplu: /usr/etc/httpd. AccessConfiguration şi ResourceConfiguration – calea fizică pe care se găsesc fişierele de configurare pe server. este o valoare între 0-65536.directorul ce conţine fişierele pe care le pune la dispoziţie httpd-ul. 23 . implicit este 80.

Utilizatorii îşi creează directorul Web.infocib. ce conţine documentaţie: < Directory/usr/local/etc/httpd/htdocs> OptionsIndexes FollowSymLinks Allow Override All * pentru .ro DocumentRoot /usr/local/etc/httpd/htdocs UserDir Web DirectoryIndex index.conf: port 80 User nobody Group #2 ServerAdmina dmin_nume@www.conf .fişierul de configurare al accesului – defineşte politica de limitare a dreptului de acces la diferitele documente ale serverului.server/~username/nume_fişier.ase.ase.htaccess files < Limit GET > 24 . în cadrul home directorului. cât şi în home-ul utilizatorilor trebuie să existe directorul Web. Atât în zona sistem.infocib.hhtaccess DefaultType text/plain Alias /icons/ /usr/local/etc/httpd/icons Alias /info/ /usr/local/etc/httpd/htdocs/info Alias /document/ /u/pub/document ScriptAlias /cgi-bin/ /usr/local/etc/httpd/cgi-bin Configurarea accesului pentru directorul htdocs. unde se depun documentele .html FancyIndexing on DefaultIcon /icons/unknown.html. trebuie să i se pună atributele de read şi execute pentru alţii. Accesul la fişiere se va face astfel: http://www.pid ServerName www.??* *~ *# */HEADER* */README* AccessFileName .default. Pentru ca ceilalţi utilizatori să aibă acces la acest director.ro ServerRoot /usr/local/etc/httpd ErrorLog logs/error_log TransferLog logs/httpd.xbm ReadmeName README HeaderName HEADER IndexIgnore */.Servere Web access.html Exemplu de fişier httpd.

reîncărcând fişierele de configurare şi redeschizând fişierul de login (log file). Pentru aceasta trebuie introdusă comanda: "/usr/etc/httpd &" în rc. -vv.conf. restartează un httpd ce deja rulează. verbose – comută pe colectorul de depanare. cel folosit drept fişier de configurare.local sau rc. -restart. Forma generală de lansare a unui server httpd este următoarea: httpd [-opt -opt -opt . very verbose – comută pe mult mai multe mesaje de depanare. 25 . portul de ascultare.conf se găseşte la locul implicit şi este specificat şi portul pe care trebuie să asculte. Acesta este pornit printr-un fişier de comandă.Reţele de calculatoare Order Allow.. Este o cale mult mai rapidă (recomandată). implicit se consideră /etc/httpd. pe sistemele Unix. În cazul în care nu se pune. Dacă se utilizează modul stand-alone. doar pentru opţiunea de "proxy". doar root-ul poate rula httpd pe porturi mai mici decât 1024. -v. -gc_only.local şi rulează continuu ca un daemon de "sendmail". Porturile mai mici decât 1024 sunt privilegiate. dacă fişierul de configurare /etc/httpd.] [director] unde opt poate fi: -r fişier_de_Configurare. El aşteaptă sosirea conexiunilor şi serveşte cererile. de exemplu /etc/rc. -l log_fişier înregistrează cererile de conectare. La fiecare cerere a clientului creează o copie a sa. ceilalţi useri având acces de la 1024 în sus. din inetd (Internet Daemon) – serverul este administrat printr-un superdaemon care ascultă un port TCP/IP şi se ocupă cu lansarea procesului httpd la fiecare cerere a unui client (inetd-ul facând swap către httpd). -p port. Deny Allow from all < / Limit > < / Directory > * implicit este Deny Etapele de instalare a serverului httpd: prin rularea stand-alone – serverul se execută ca un daemon clasic. Fără acest argument se consideră că se rulează ca "inetd" şi utilizează stdin şi stdout drept canale de comunicaţie. poate fi: httpd [-d director_iniţial_server] [-f fisier_de_configurare][-v] unde -v este opţiunea pentru afişarea versiunii de server http.. Se poate renunţa la semnul de background "&". care sunt privilegiate. Un exemplu de formă de rulare a serverului.

structură de directoare (asemănătoare cu NCSA). -dty. -ds vizualizare selectivă a directorilor. then (/usr/etc/httpd && (echo -n 'httpd')) & >/dev/console fi Dacă sunt probleme la instalare. incluzând textul fişierului în partea superioară a directorului. Exemplificaţi pentru Apache sub SO Windows şi sub SO Unix. cu fişierul de configurare de mai sus. -dt pentru toţi directorii navigabili care conţin un fişier README. Dacă se doreşte renunţarea la server atunci se poate folosi: if [-f /usr/etc/httpd]. Exemplu: httpd -r /usr/etc/httpd. o acţiune de încercare a accesului în directori va genera un mesaj de eroare. idem. 26 . Aceste două opţiuni pot fi combinate cu -dy.5 Apache Caracteristici: Versiuni sub SO Unix (/var/apache/) şi SO Windows (c:\Apache\). -dr dezactivează includerea fişierului README. -db. înainte de listarea conţinului directorului (se setează directiva de configurare DirReadme). -dn nu permite vizualizarea directorilor. Acestă opţiune se poate seta şi din directiva de configurare DirAccess. aceştia devenind nişte documente hipertext. 3.Servere Web -version afişează versiunea de httpd şi libwww (The WWW Common Library). consultarea documentaţiei referitoare la bug-uri. Fişiere de configurare (asemănătoare cu NCSA). -dy dă posibilitatea vizualizării (navigării) conţinutului directorilor. dar pune textul fişierului README în partea inferioară. accesul fiind permis doar pentru cei conţinuţi în fişierul www_browsable. -dys. se recomandă rularea cu opţiunea -v şi citirea FAQ-ului corespunzător. Exemplificaţi pentru Apache sub SO Windows şi sub SO Unix. etc.conf -p 80 este un server standalone ce rulează pe portul 80.

6.ase. Unde se găsesc aceste servere? (/usr/local/etc/httpd/.pdf 3. pentru a accesa paginile voastre de Web cu serverul de Web NCSA...html create în seminarul anterior. 3. pornire manuală pe portul 8080 c. APACHE sub SO Windows 1.ro) Verificaţi ce servere de Web rulează (NCSA. /var/apache/.ase.ase. utilizând fiecare server de Web instalat. Accesaţi pagina voastră de Web de pe infocib. 2.-----------/apachedocs. în care mutaţi fişierele .ro:1800).Reţele de calculatoare Documentaţie http://www. Accesaţi o pagină situată în alt subdirector din Web. cu toate subdirectoarele sale. Apache 1. Dar pentru Apache? Transferaţi pe server fişierele . Download kit: ftp://ecomm. Instalare: a. Daţi dreptul de citire şi execuţie pentru toată lumea directorului Web.org/ şi local. Care este denumirea directorului pe care trebuie să-l creaţi în Home Directory. apache) (ps aux). 10. directorul c:\apache\ 27 . Documentaţi-vă despre directivele care vă permit crearea unor servere virtuale. 7. (~cont). Documentaţie: --------.. 3. 4. 5.) Pe ce porturi rulează (netstat –a). Creaţi în home directory un director Web.6 Exerciţii NCSA.ro/ /apache2_0.43-win32-x86no_ssl. ce versiune de software? (httpd –help) Vizualizaţi structura de directoare şi fişierele de configurare pentru fiecare în parte. Creaţi un mic script SHELL (pentru a-l pune în zona cgi-bin). Conectaţi-vă pe un server de Unix (exp: infocib.html. 11. după instalare Apache sub SO Windows sau sub SO Unix (infocib.apache. Studiaţi documentaţia apache sub Unix de pe server.msi 2. 8. alegeţi varianta custom b. care să afişeze de câte ori a fost vizitată pagina voastră (opţional). 9.

Ce module sunt încărcate? Cum se pot încărca celelalte? (-V. Vizualizaţi structura de directori ai serverului apache. Testaţi-l pe default. k. b. f. Verificaţi dacă programul apache este pornit ca proces sau serviciu. Puneţi în cgi-bin un script care să vă afişeze un contor pe pagina voastră. m. e. c.htpasswd: <Directory "F:\users"> AllowOverride AuthConfig Options None Order allow. h. g. Verificaţi noul server de Web de pe acest port (apache –t.conf. j. Verificaţi dacă este portul 8080 ocupat. Verificaţi existenţa serviciului. . Verificaţi ce opţiuni aveţi din linie de comandă pentru comanda „apache” (apache -?).Servere Web 4. care sunt ocupate.htaccess. Accesaţi paginile noului server. Atenţie la aspectele de securitate: <Files ~ "^htaccess"> Order allow. Configurare: a. n. i. netstat -a). l.conf. i. Verificaţi configuraţia (apache –t).deny Allow from all </Directory> ii. Porniţi serverul apache ca serviciu. Creaţi un nou fişier de configurare (alt nume. modificaţi denumirea fişierelor . Vizualizati si modificati fişierul httpd. cât şi pentru un alt director. Porniţi serverul cu acest fişier nou şi testaţi-l (–f file_name). alt port).deny 28 . pe care le puteţi folosi ca utilizator privilegiat şi ca utilizator obişnuit. -l). astfel încât home-ul pentru utilizatori să fie: c:\stud_document\ (exp: Alias /users "F:\users" ). Documentaţi-vă în legătură cu porturile unui sistem. Editaţi httpd. Intraţi în directorul bin. Intraţi cu cont şi parolă pe directorul vostru virtual. d. Porniţi serverul apache ca proces din linie de comandă (nu din meniu). o.

deny Deny from all </Files> iii. NameVirtualHost * <VirtualHost *> DocumentRoot "F:/users/carmen" ServerName carmens2 # Other directives here </VirtualHost> <Directory "F:\users"> AllowOverride AuthConfig Options None Order allow. (Fişierul hosts trebuie editat).deny Allow from all </Directory> 29 . (-t –D DUMP_VHOST). Verificaţi-l. Creaţi un server virtual pe aceeaşi adresă IP. Creaţi fişierul de parole în directorul vostru: C:\apache\bin\htpasswd –c htpasswd cs p. Trebuie pus şi modulul „LoadModule vhost_alias_module modules /mod_vhost_alias. Creaţi în directorul vostru fişierul htaccess: AuthType Basic AuthName "Carmen's Area!" AuthUserFile "F:/users/carmen/htpasswd" require user cs iv.Reţele de calculatoare Deny from all </Files> <Files ~ "^htpasswd"> Order allow.so”? Testaţi noul site (http//nume2:port).

deschideţi o fereastră de comandă (Start->Programs->Accessories>Command Prompt). Pentru informaţii referitoare la modul în care se folosesc. Utilitare pentru depanarea erorilor de configurare şi testarea conectivităţii Tabel 4. deoarece pot fi folosite atât la depanarea erorilor de configurare.4 Utilitare TCP/IP 4. Pentru a folosi utilitarul hostname. urmată de parametrul/?. cu excepţia hostname şi tracert. trebuie doar să tastaţi numele acestuia şi să apăsaţi tasta Enter. Dacă informaţiile afişate încap pe mai mult de un ecran şi nu le puteţi urmări. folosiţi parametrul |more. tastaţi numele acestuia şi apăsaţi tasta Enter.1 Utilitar Descriere Testează conexiunea cu un computer ping Afişează conţinutul cache-ului local în care sunt stocate arp adresele IP asociate adreselor fizice ale plăcilor de reţea (MAC) pentru computerele din LAN Afişează configuraţia TCP/IP curentă ipconfig Afişează statistici şi conexiuni pentru protocolul NetBT nbtstat Afişează statistici şi conexiuni pentru protocolul TCP/IP netstat Afişează sau modifică tabela de rutare locală route hostname Afişează numele computerului Verifică ruta până la un computer aflat la distanţă tracert Verifică dacă routerele de pe drumul până la un computer aflat pathping la distanţă funcţionează corect şi în acelaşi timp detectează pierderile de pachete de date rezultate în urma trecerii prin diferite noduri ale reţelei Toate aceste utilitare sunt executate din linia de comandă. Va fi afişat numele computerului. Pentru informaţii referitoare la modul de folosire a utilitarului tracert. şi tastaţi comanda. cât şi la aflarea de informaţii referitoare la configuraţia curentă.1 Utilitare TCP/IP Utilitarele linie de comandă TCP/IP prezintă o mare importanţă. 30 .

se foloseşte parametrul /all. dacă este cazul. Ping transmite pachetele utilizând ICMP ECHO_REQUEST şi se aşteaptă primirea unui 31 . Rulează comenzi pe un computer pe care este instalat UNIX.Reţele de calculatoare Utilitare pentru conectarea la distanţă folosind protocolul TCP/IP Utilitar FTP TFTP Telnet RCP RSH REXEC Tabel 4.2 Descriere Facilitează transferul bidirecţional de fişiere între un computer pe care rulează Windows şi un server FTP (de exemplu. Sistemele de operare Microsoft nu oferă suport decât pentru clienţi telnet. Pentru afişarea tuturor informaţiilor disponibile.0. Rezultatul tastării comenzii ipconfig /all este următorul: Dacă este setată o configuraţie validă. Facilitează transferul bidirecţional de fişiere între un computer pe care rulează Windows şi un server TFTP. Utilitarul ipconfig Ipconfig se foloseşte pentru verificarea configuraţiei protocolului TCP/IP. Windows 2000 Server). va fi afişată adresa IP folosită. Dacă Windows nu a putut obţine o adresă IP de la un server DHCP. Oferă o conexiune la un computer ce suportă protocolul telnet. precum şi gateway-ul implicit. Rulează un proces pe un computer aflat la distanţă. de exemplu un computer pe care rulează UNIX. Dacă este detectat în reţea un duplicat al adresei IP folosite. este afişată adresa IP şi masca de subreţea. dar în dreptul măştii de subreţea se va trece 0. Utilitarul ping Ping este un instrument folosit pentru testarea conexiunii TCP/IP între computerul dumneavoastră şi unul aflat la distanţă. Vom descrie în continuare în detaliu o serie de utilitare TCP/IP. Copiază fişiere între un computer cu Windows şi unul ce oferă suport pentru RCP (Remote Copy Protocol).0.0. va fi afişată adresa alocată prin tehnologia APIPA.

32 . numele terminalului.Utilitare TCP/IP răspuns de confirmare pentru fiecare pachet transmis prin ICMP ECHO_REPLY. precum şi alte caracteristici. Opţiuni . conecţiile active. Vom prezenta o serie de opţiuni folosite cu această comandă. numele complet. În momentul în care nu există intrări ARP pentru o anumită adresă Internet se va afişa un mesaj în acest sens.selectiv: Format de redare redus -b -f Suprimă afişarea părţii de antet -i Afişează o listă cu timpii inactivi -l Format de redare extins -q Afişează o listă rapidă de utilizatori Utilitarul netstat Comanda netstat este folosită pentru a extrage o serie de informaţii cum ar fi tabelele de rutare. -a Solicită afişarea stării socketurilor. fluxuri. Utilitarul arp Comanda arp afişează şi modifică tabela de corespondenţă între adrese Internet şi adrese Ethernet (MAC). Cele asociate cu procesele server nu sunt afişate -i Afişează starea interfeţelor ce au fost autoconfigurate -m Afişează modul de utilizare a memoriei -r Afişează tabelele de rutare -p nume_protocol Limitează informaţiile la un protocol anume Utilitarul traceroute Este utilizat pentru a identifica traseul ce trebuie urmat de un pachet pentru a ajunge la destinaţie. Această comandă lucrează utilizând un câmp special TTL (time to live) din cadrul pachetului IP. Utilitarul finger Listează numele de login. Sintaxa comenzii este ping adresa_IP_a_computerului_de_la_distanţă.

Reţele de calculatoare Opţiuni: -a -d nume Afişează toate intrările din tabele ARP curentă Şterge intrările corespunzătoare din tabela ARP -s adresă host Crează o nouă intrare în tabela ARP folosind o adresă Ethernet 4. ping 127. ipconfig Folosiţi utilitarul ipconfig pentru a verifica dacă a fost iniţializată configuraţia TCP/IP. va trebuie să urmaţi succesiunea de paşi de mai sus pentru a putea localiza problema.2 Testarea unei configuraţii TCP/IP Vom prezenta în continuare care sunt paşii ce trebuie urmaţi pentru verificare configuraţiei computerului şi pentru testarea conexiunilor la computere aflate la distanţă.0. atunci ceilalţi paşi sunt inutili. În general. ping adresa_IP_a_unui_computer_aflat_la_distanţă (pe alt segment de reţea) Folosiţi utilitarul ping cu adresa IP a unui computer aflat pe alt segment de reţea (de exemplu. dacă acest ultim pas reuşeşte.1 Folosiţi utilitarul ping cu adresa internă a plăcii de reţea pentru a verifica dacă protocolul TCP/IP este instalat corect şi placa dumneavoastră de reţea îl foloseşte. Totuşi.0. infocib sau nemesis) pentru a verifica dacă se poate stabili o conexiune cu un computer aflat la distanţă prin intermediul unui router. 33 . ping adresa_IP_a_gateway-ului_implicit Folosiţi utilitarul ping cu adresa IP a gateway-ului implicit (aceasta poate fi aflată folosind comanda ipconfig) pentru a verifica dacă gateway-ul implicit este operaţional şi computerul dumneavoastră poate să comunice cu acesta. ce implică eventual şi existenţa unor routere. ping adresa_IP_a_computerului_dumneavoastră Folosiţi utilitarul Ping cu adresa IP a computerului dumneavoastră pentru a elimina riscul existenţei în reţea a unui duplicat al adresei IP folosite. în cazul în care nu reuşeşte.

Utilitare TCP/IP

4.3 Exemple de folosire a unor utilitare TCP/IP Arp –a – afişează conţinutul cache-ului ARP (adrese IP asociate adreselor fizice ale plăcilor de reţea). Folosiţi mai întâi comanda ping pentru ca Windows să poată stoca adresa fizică (MAC) a plăcii de reţea folosită de computerul aflat la distanţă. Ex: Secvenţa ping ecomm.ase.ro arp -a va duce la afişarea adresei MAC a serverului ecomm. tracert adresa_IP_a_computerului_de_la_distanţă – afişează nodurile de reţea prin care trece un pachet de date până să ajungă la computerul destinaţie. pathping adresa_IP_a_computerului_de_la_distanţă – reprezintă o combinaţie între comenzile tracert şi ping, fiind testată conexiunea cu fiecare nod de reţea (router) până la computerul destinaţie, folosindu-se comanda ping în mod automat pentru fiecare dintre acestea. nbtstat –A adresa_IP_a_computerului_de_la_distanţă – afişează numele NetBIOS al unui computer aflat la distanţă, în cazul în care este cunoscută adresa IP a acestuia. netstat –a – afişează toate conexiunile stabilite în reţea, precum şi toate porturile deschise pe computerul dumneavostră.

34

5 Adresare IP
5.1 Clase de adrese Fiecare familie de protocoale trebuie să conţină un mod de adresare, pentru a identifica reţelele şi nodurile în cadrul acestora. Adresele Internet folosite de IP sunt reprezentate pe 32 de biţi şi sunt alocate în mod unic la nivel global, de o autoritate centrală şi mai multe autorităţi regionale. Adresele pe 32 de biţi sunt specificate de aşa-numita vesiune 4 a IP. Recent a fost standardizată versiunea 6 (IPv6), în care adresele se reprezintă pe 128 octeţi. În vederea unei alocări sistematice, adresele IP au fost divizate în cinci clase de adrese. Dintre acestea trei (clasa A, B, C) vor fi discutate în amănunt. Orice nod conectat într-o reţea TCP/IP trebuie să aibă o adresă IP (ruterele, care dispun de mai multe interfeţe de reţea, vor avea câte o adresă IP pentru fiecare interfaţă). A fost introdusă şi o convenţie de scriere a acestor adrese: fiecare din cei patru octeţi ai adresei este notat distinct prin numărul zecimal corespunzător, cele patru valori fiind separate prin punct, ca în exemplul următor: 123.1.232.11. O altă convenţie de scriere este următoarea: 20.0.0.0/12, ce denotă aplicarea unei măşti de 12 biţi pe adresa 20.0.0.0, adică selectează toate valorile posibile în ultimii 20 biţi de adresă. Analog, 194.110.6.0/26 aplică o mască de 26 biti pe adresa 194.110.6.0/, adică selectează ultimii şase biţi de adresă (64 valori). Recent a fost introdusă şi distincţia între adrese publice şi adrese private. Se numesc adrese publice cele care sunt obţinute de la autorităţile de alocare a adreselor şi sunt rutate în Internet. Aceste adrese au caracter de unicitate, în sensul că nici o adresă nu este multiplu alocată. Datorită creşterii explozive a conectărilor la Internet a apărut preocuparea faţă de epuizarea adreselor pe 32 de biţi şi una din soluţiile adoptate pentru evitarea acestui fenomen a fost să se rezerve câteva adrese care să poată fi utilizate intern (privat) de orice organizaţie, fără a fi vizibile în afara organizaţiei (nu vor fi rutate în afara organizaţiei). Astfel de adrese sunt: 10.0.0.0 - 10.255.255.255 (reţea de clasă A) 172.16.0.0 - 172.16.255.255 (reţea de clasă B) 192.168.0.0 - 192.168.255.255 (bloc de reţele de clasă C) 35

Adresare IP

Rămâne la latitudinea utilizatorului alegerea adreselor private pe care le foloseşte, dar aceasta trebuie făcută conform unor criterii de performanţă. Unul dintre criteriile de alegere este evident dimensiunea reţelei interne: dacă aceasta are doar câteva zeci de calculatoare nu se justifică alegerea adreselor private de clasă B sau A. Sintetizarea noţiunilor referitoare la adresarea IP Tabel 5.1 Denumire Adresa IP Adresă de reţea Descriere Număr pe 32 biţi, scris de obicei în format zecimal, grupat pe cei patru octeţi, prin care se poate identifica în mod unic un nod (interfaţă). Număr pe 32 biţi, scris de obicei în format zecimal, grupat pe cei patru octeţi, care identifică o reţea. Numărul nu poate fi asignat unui nod (interfeţă). Porţiunea din adresă corespunzătoare gazdei conţine numai valori binare de 0. Număr pe 32 biţi scris de obicei în format zecimal grupat pe cei patru octeţi, utilizat pentru a adresa toate nodurile (interfeţele) din cadrul unei reţele de calculatoare. Porţiunea din adresă corespunzătoare gazdei conţine numai valori binare de 1. Număr pe 32 biţi scris de obicei în format zecimal grupat pe cei patru octeţi, utilizat pentru a calcula adresa de reţea prin efectuarea unui şi logic între mască şi o adresă IP.

Adresă de broadcast

Mască de reţea

Prin definiţie, toate nodurile dintr-o reţea posedă aceeaşi valoare numerică pentru porţiunea de reţea din adresele IP. Cealaltă parte a adresei IP se numeşte zonă de gazdă (host). Aceasta diferă de la un nod (interfaţă) la altul. Adresele de clasa A sunt folosite în reţelele cu un număr foarte mare de noduri aflate sub aceeaşi autoritate (companii transnaţionale, organizaţii mondiale, etc.). Adresele de clasă A folosesc opt biţi (un octet) pentru a identifica reţeaua. Prin urmare ceilalţi 24 biţi sunt folosiţi pentru a identifica nodurile (interfeţele). Prin urmare unei reţele de clasă A i se pot asigna 224 noduri. Adresele de clasa B au rezervată o zonă de reţea de 16 biţi, iar cele de clasă C au rezervată o zonă de reţea de 24 biţi.

36

0 este folosită ca adresă de broadcast.0.2 A 1 (8) 3 (24) B 2 (16) 2 (16) C 3 (24) 1 (8) *Există două adrese rezervate pentru fiecare reţea.2 A B C 1.0 – 214 – 2 191. 192.0 identifică o reţea de clasă B.0 identifică o reţea de clasă A.2 216 .4. Marje adrese IP Clasă Valoarea primului octet 1 .2 Numărul de adrese asignabile pe reţea* 24 2 -2 216 .0.0 27 – 2 128. De exemplu.0.255.0 şi 223. La nivel conceptual adresele de reţea referă grupul tuturor adreselor IP dintr-o reţea.0. Tabelul 3 sintetizează aspectele referitoare la adresele de reţea.0. Adresele de reţea sunt similare adreselor IP obişnuite însă nu sunt asignabile unei interfeţe anume.0 identifică o reţea de clasă C.223 Adrese de reţea valide Număr de adrese de reţea valide Tabel 5.0. Alte exemple de adrese rezervate ar fi: 128.126 128 – 191 192 .255.0 este folosită ca adresă de loopback.0.0 192.254.0. Tabelul 2 sintetizează aceste caracteristici.0.0.255.0.0.0.9.1. iar adresa 127. adresa 0.0.0.3. De exemplu adresa 7.Reţele de calculatoare Adresele de clasa B au fost atribuite iniţial marilor universităţi şi companii.1. Caracteristici adrese Clasă Număr de octeţi-biţi utilizaţi pentru a identifica reţeaua Număr de octeţi-biţi utilizaţi pentru a identifica interfaţa Tabel 5. iar 200.0. 130.0. 191.0.0.255.0.0 – 221 – 2 223. În ultima vreme obţinerea unei adrese de clasa B este dificilă.3 Numărul de adrese asignabile pe reţea 224 .0 – 126.254. 37 .2 28 .0 Există o serie de excepţii care reies şi din tabelul 3.0.0.2 28 .

255.Adresare IP O mască de reţea standard este definită ca având valori binare de 0 corespunzător poziţiilor din adresă ce definesc host-ul.1 Structurarea unei adrese de IP Putem face o serie de observaţii privitoare la cele discutate: Două adrese IP unice din aceeaşi reţea au valori identice pentru partea de reţea. Astfel. În tabelul 4 sunt definite măştile de reţea standard. determină un număr de patru biţi de host. iar cei de subreţea sunt obţinuţi prin preluarea biţilor rămaşi.4 Masca de reţea standard 255. sunt definite trei zone: reţea. Biţii ce identifică reţeaua sunt definiţi prin tipul clasei.240. 8 24-x x Reţea Sub-reţea Host 16 16-x x Reţea Sub-reţea Host 24 8-x x Reţea Sub-reţea Host Figura 5. De exemplu o mască de reţea de forma: 255.0.255. 38 .0 255.255. subreţea şi host.0.0. Măşti de reţea standard Clasă A B C Număr de octeţi-biţi ce identifică reţeaua 1 (8) 2 (16) 3 (24) Tabel 5.255. utilizată în cadrul unei reţele de clasă C.0 În momentul în care se doreşte împărţirea în subreţele se alocă în cadrul adresei IP un număr de biţi care identifică subreţelele. diferind prin partea de host.0 255. Aceştia sunt preluaţi din cadrul zonei de host a adresei IP. cei de host sunt definiţi de către masca de reţea folosită.255. în cadrul adresei IP.

iar masca este 255.11 şi masca de reţea 255.255.Reţele de calculatoare Două adrese IP unice din aceeaşi subreţea au valori identice în partea de reţea.193.255. rezultă că nu se utilizează împărţirea în subreţele.0 1000 0110 1000 1101 0000 0111 0000 0000 2. Adresa este de clasa B.255.193. Adresa: Masca de reţea: Rezultatul: 193. Având adresa IP 134.0 să se specifice care este adresa de broadcast pentru subreţea.255.7.255.7. Ţinând cont că este vorba despre o adresă de clasă C. am evidenţiat îngroşat biţii care identifică subreţeaua.255.255. Dacă nu s-ar utiliza împărţirea în subreţele. cel mai mic grup de hosturi ce s-ar putea forma ar fi echivalent cu o clasă de adrese (A.255.255. Adresa: Masca de reţea: Rezultatul: 134.0 1111 1111 1111 1111 1111 1111 0000 0000 193.7 1100 0001 1100 0001 0000 0111 0000 0111 3.0. Numărul de reţele disponibile ar fi insuficiente.2 Exerciţii rezolvate 1.7.7. Având adresa IP 134.7.7 1100 0001 1100 0001 0000 0111 0000 0111 255.11 şi masca de reţea 255. B sau C au aceeaşi valoare în partea de reţea şi diferă prin partea de subreţea.141.255.0 să se specifice care este numărul care identifică subreţeaua. 5.255.7.7 şi masca de reţea 255.141.141.193.0 să se specifice care este adresa care identifică subreţeaua. B sau C în funcţie de caz).0 1111 1111 1111 1111 1111 1111 0000 0000 134. Având adresa IP 193. în cea de subreţea diferind doar prin partea de host.11 1000 0110 1000 1101 0000 0111 0000 1011 255.141.255. Două adrese IP unice aflate în subreţele diferite dintr-o reţea de clasă A.7. 39 .

1.1 şi masca de reţea 255.0.7.1.0.2.0.7.7.255 1000 0110 1111 1111 1000 1101 0000 0111 1111 1111 1111 1111 1000 1101 0000 0111 1000 1101 0000 0111 4.255.0 1111 1111 0000 0000 134.141.0 să se specifice care sunt adresele IP asignabile în această subreţea.193.0 10.7 şi masca de reţea 255.7. fiecare cu maximum 200 noduri.255. S1 S2 S3 S4 S5 S6 Sn 0000 1010 0000 0000 0000 0000 0000 0000 0000 1010 0000 0000 0000 0001 0000 0000 0000 1010 0000 0000 0000 0010 0000 0000 0000 1010 0000 0000 0000 0011 0000 0000 0000 1010 0000 0000 0000 0100 0000 0000 0000 1010 0000 0000 0000 0101 0000 0000 0000 1010 1111 1111 1111 1111 0000 0000 10.193.1.1.255.254.1.0 10. Adresa de subreţea este 140. Adresa este de clasă A.140.5.0 să se specifice care sunt subreţelele ce se pot forma. iar cea de broadcast este 140.0.255. Reţeaua poate creşte până la un număr de maxim 100 de subreţele. 6. Având adresa IP 193.0 10.141.4.255.0.193.193.248 să se specifice care sunt adresele IP asignabile în această subreţea. iar cea de broadcast este 193.1 .6. Adresele de IP asignabile se găsesc în intervalul 193.7.0 10.5.7.255.1.7.0 7.0 10. Să se proiecteze o reţea care să cuprindă trei situri Ethernet legate prin linii seriale. Se va folosi adresa de reţea 40 . Acest lucru implică faptul că octeţii 2 şi 3 sunt în întregime rezervaţi pentru identificarea subreţelelor.3 şi masca de reţea 255.1.3.255. 5. Adresele de IP asignabile se găsesc în intervalul: 140.0.11 1000 0110 0000 1011 255.193.0.7.1.118.Adresare IP Adresa: Masca de reţea: Rezultatul: Adresa de broadcast 134.1.255.7.141.1.1 .0 10.0. Adresa de subreţea este 193. Având adresa IP 140.255.0 1000 0110 0000 0000 134.1.0. Având adresa IP 10.255.193.255.

Există două posibilităţi de mască de reţea: 255. Acest bit a fost marcat cu X.255. Vom continua pe primul model.16.0.255. În concluzie masca de subreţea va avea următoarea formă: 11111111 11111111 1111111X 00000000 Biţi de reţea Numărul minim de biţi de subreţea Numărul minim de biţi de host Observăm că rămâne un bit care poate fi asignat atât grupului de biţi ce identifică subreţeaua. cât şi grupului de biţi care identifică hostul.0. Arhitectura este cea prezentată în figură.254. Dacă am avea 7 biţi pentru host ar însemna că am putea identifica 27 -2 (126) interfeţe.Reţele de calculatoare 172. Numărul de subreţele necesar este 100. Să se determine măştile de subreţea care îndeplinesc criteriile date. ceea ce ar fi insuficient pentru a acoperi necesarul de 200 adrese. ceea ce implică un număr minim de şapte biţi rezervaţi.0 sau 255. Ruterul A Ruterul B Ruterul C Rezolvare Masca trebuie să aibă minim 8 biţi pentru host.255. Primii 16 biţi vor avea valoarea 1. 41 . deoarece adresa indicată este de clasă B. deoarece cel de-al doilea este mai simplu. deoarece 27 este cea mai mică putere a lui doi mai mare decât 100.0.

0 Vom selecta primele şase subreţele aşa cum reiese şi din tabelul următor: Subreţea Router A Ethernet Router B Ethernet Router C Ethernet Linie serială A-B Linie serială A-C Linie serială C-B Mască de subreţea 255.3 (B) 172.16.16.254.16.8..16.2 (B) 172.8.6.0..255.254.16.0 Adresă subreţea 172.16.4.0 172.0/23 Ruterul C Subreţeaua 172..0 172.0.8..254. 172..16.254.0 172.16.8.255.0 255.0 Adresa IP router 172.0 .0 172.16.16.6.1 172..16..3 (C) Subreţeaua 172.10.4...16.16.10.16.4.255...0 172.Adresare IP Subreţelele ce se pot forma sunt: 172.0.0 255.0/23 Subreţeaua 172.1 (A) şi 172.16.1 (A) şi 172.16.254.252.10.0/23 Ruterul A Subreţeaua 172.0 255.255.16.0.255..0 172.3 172.0 172..16.2.16.16.0/23 Subreţeaua 172.2.0/23 Ruterul B Subreţeaua 172..0.16.16....2 (B) şi 172.254..16..0 255.2.10.2 172.0/23 42 .6.2.255.16..0 172.16.254.0 255.16.4.

6 Comunicaţie client-server la nivel de socket
6.1 Introducere Vom prezenta o serie de aspecte generale: Protocoalele TPC/IP de nivel transport oferă servicii ce permit programelor nivelului aplicaţie să comunice între ele prin intermediul mesajelor. Când o aplicaţie trimite o cerere către nivelul transport pentru a trimite un mesaj, protocolul folosit la acest nivel: • împarte informaţia în pachete; • adaugă un antet de pachet care include adresa destinaţiei; • trimite informaţia nivelului reţea pentru procesare ulterioară. Transmisia şi recepţia datelor se realizează prin intermediul unor porturi de pe server, care identifică destinaţia specifică a mesajului. Nivelul transport este implementat în reţelele TCP/IP prin intermediul a două protocoale: • UDP (User Datagram Protocol) – protocol datagramă utilizator; • TCP (Transmission Control Protocol) – protocol de control al transmisiei. Caracteristici UDP: Asigură servicii de tip datagramă nivelului aplicaţie; Nu este fiabil (nu asigură certitudinea livrării datagramelor, nici mecanismele de protecţie la pierderea sau duplicarea datagramelor); Viteză mare de transmisie; Este un serviciu fără conexiune (emiţătorul nu cunoaşte starea receptorului în momentul transmisiei); Pentru transferul datelor foloseşte nişte entităţi abstracte, numite porturi de protocol, identificate prin numere întregi pozitive şi care au asociate nişte cozi de mesaje prin care se transmit mesajele; Se utilizează pentru mesaje mici (sub 8KB) cu viteză mare; 43

Comunicaţie client-server la nivel de socket

Antetul datagramei UDP conţine: • Source Port Number – adresa portului sursă; • Destination Port Number – adresa portului destinaţie; • Length – lungimea datagramei în bytes; • Checksum – suma de control asociată datagramei (foloseşte acelaşi algoritm ca la protocolul IP). Caracteristici TCP (Transmission Control Protocol): Este fiabil (asigură integritatea datelor transmise, mecanisme de protecţie la pierderea sau duplicarea pachetelor, păstrarea numărului de secvenţă, mecanisme de control al fluxului de date în reţea). Asigură transmisia blocurilor continue de date între porturile de protocol asociate aplicaţiilor. Dimensiunea mesajelor nu este limitată. Viteza de transfer mai mică. SO oferă programelor la nivel aplicaţie o interfaţă comună pentru aceste două protocoale, şi anume interfaţa socket.

6.2 Interfaţa Socket Este o interfaţă între un program de aplicaţie şi serviciul de transport (este un standard de facto), fiind furnizat de o bibliotecă socket sau de sistemul de operare. Se foloseşte conceptul de descriptor, fiecare socket fiind tratat asemănător cu un fişier local. Acest descriptor este transmis aplicaţiei la crearea socket-ului şi apoi este utilizat ca argument în apelurile următoare. Primitive de serviciu Socket API Tabel 6.1
Primitive socket(protofamily, type, protocol) close(socket) bind(socket, localaddr, addrlen) listen(socket,queuesize) newsock = accept(socket, caddress, caddresslen) connect(socket, saddress, saddresslen) Descriere creează un socket închide un socket leagă socket-ul cu un port pune socket în mod pasiv acceptă o cerere de conectare stabileşte legătura cu un server care a făcut accept

44

Reţele de calculatoare Primitive send(socket, data, length, flags) sendto(socket, length, flags, destaddress, addresslen) sendmsg(socket, msgstruct, flags) recv(socket, buffer, length, flags) recvfrom(socket, buffer, length, flags, sndaddr, saddrlen) rcvmsg(socket, msgstruct, flags) Descriere transmite un mesaj transmite un mesaj folosind un socket neconectat primeşte un mesaj primeşte un mesaj pe un socket neconectat

Proprietăţi ale socketurilor în Unix: inovaţie a sistemului Berkeley UNIX; este un punct de comunicaţie prin care un proces poate emite sau recepţiona informaţie sub forma unui flux de bytes; este identificat printr-un descriptor, asemănător cu cel pentru fişier realizează următoarele operaţii elementare: • conectarea la staţia de la distanţă • emiterea datelor • recepţionarea datelor • închiderea unei conexiuni • ataşarea la un port • aşteptarea cererilor de conexiune emise de staţiile de la distanţă • acceptarea cererilor de conexiune la portul local O aplicaţie de reţea include: un program client – care creează un socket pentru a iniţia o conexiune cu o aplicaţie server un program server – care aşteaptă preluarea cererilor clienţilor Structura generală folosită pentru lucrul cu socketuri este: struct sockaddr { unsigned short sa_family; char sa_data[14]; //14 bytes pentru adrese }

45

// }. struct sin_addr. Pentru a lucra mai uşor cu structura de mai sus se foloseşte o nouă structură ajutătoare sockaddr_in. sin_zero[8] se iniţializează cu 0. Structura ajută la referirea facilă a elementelor adresei de socket: struct sockaddr_in { short int sin_family. Pentru acest lucru va trebui să se facă conversia între formatul little endian (host order) şi cel big endian (network order).Comunicaţie client-server la nivel de socket Membrii structurii sunt: sa_family identifică familia de adrese. sin_addr identifică adresa IP. Membrii: sin_family corespunde câmpului sa_family din structura sockaddr. struct in_addr *inp) 46 . O altă funcţie ce poate fi folosită în locul celei de mai sus este inet_aton() cu prototipul: int inet_addr(const char *cp. unsigned char sin_zero[8]. unsigned short int sin_port. Valorile articolelor sin_port şi sin_addr trebuie să fie în forma big endian. care converteşte adrese IP din forma zecimală grupată în cea de tipul unsigned long în formatul big endian. Pentru aceste conversii se vor utiliza funcţiile: htons() – “host to network short” htonl() – “host to network long” ntohs() – “network to host short” ntohl() – “network to host long” O altă funcţie utilă de conversie este inet_addr(). sa_data identifică adresa de socket compusă din numărul portului şi adresa IP. sin_port identifică portul. Structura sockaddr este una generică (o putem privi ca o clasă abstractă) menită a stoca informaţii de adresă pentru oricare tip de socketuri.

denumit port. 2 1 0 . pentru domeniul AF_INET şi tipul SOCK_STREAM se va considera protocolul de transport TCP. Se mai poate folosi şi constanta SOCK_RAW care oferă un acces la protocolul reţea (protocolul IP). 5 4 " . my_addr.sin_addr)).sin_port = htons(MYPORT). iar pentru cazul în 47 .Reţele de calculatoare În cazul în care avem o structură in_addr şi dorim să afişăm adresa IP în format little-endian. int tip.sin_addr)).sin_zero). în caz de eroare. Acesta poate fi setat pe “0” pentru ca funcţia să-şi poată alege protocolul corect automat. Parametrii funcţiei: Domeniul de comunicaţie poate fi setat cu valori de tipul AF_ceva. Protocol specifică protocolul particular care va fi utilizat pentru transmisia datelor. atunci putem folosi funcţia inet_ntoa(). inet_ntoa(ina. de nivel inferior. fiecare socket va avea asociată o adresă formată din adresa IP a maşinii gazdă şi un număr de 16 biţi.h> int socket (int domeniu. inet_aton( " 2 1 . local gazdei respective. memset(&(my_addr. De exemplu. #include <sys/types. &(my_addr. int protocol). cum ar fi: AF_UNIX – stabileşte domeniul de comunicare locală UNIX sau AF_INET – utilizat pentru comunicaţii între procese aflate pe aceeaşi maşină sau pe maşini diferite. ' \ 0 ' . În acest caz.h> #include <sys/socket. 8 ) . sigură. orientată-conexiune prin flux de date) sau SOCK_DGRAM (fără conexiune prin datagrame). folosind stiva de protocoale TCP/IP (domeniul Internet). Tipul de socket utilizat: SOCK_STREAM (comunicarea se va realiza full-duplex. 3 3 . Vom prezenta un exemplu de iniţializare a structurii sockaddr_in: struct sockaddr_in my_addr. astfel: printf ("%s". Pentru exemplele curente vom utiliza cea de-a doua variantă.sin_family = AF_INET. Funcţia socket() crează un socket şi returnează descriptorul de socket (valoare întreagă prin care se identifică un socket) sau –1. my_addr.

Comunicaţie client-server la nivel de socket care domain este AF_INET şi tipul SOCK_DGRAM se va considera implicit protocolul de transport UDP. 48 . socket() pentru a crea un socket. getprotobyname () socket() bind() ge thostbyname() listen() ge tprotobyname() acce pt() socke t() stabilire conexiune conne ct() read() ce rere write() răspuns close() write () read() close () Figura 6. connect() pentru a conecta socket-ul la un server.1 este prezentat modul de comunicaţie client-server TCP/IP. getprotobyname() pentru a converti numele unui protocol în forma binară folosită de sockets.1 Cient-server TCP/IP Clientul apelează: gethostbyname() pentru a converti numele unui calculator în adresa IP. 6.2.1 Comunicaţie client-server TCP/IP În figura 6.

h> #include <netinet/in. Primitiva bind() asignează socketul la portul maşinii la care.h> #include <sys/socket.Reţele de calculatoare recv() (în mod repetat) pentru transferul tuturor datelor de la server (clientul nu are de unde şti dacă serverul transmite datele într-un singur mesaj sau în mai multe). serverul va asculta cereri de conexiune din partea clienţilor. accept() pentru a accepta o cerere de conectare şi a crea un socket nou pentru această conexiune. send() pentru a trimite date. de exemplu. bind() pentru a specifica portul local pentru socket. socket() pentru a crea un socket. Prototipul funcţiei este următorul: #include <sys/types.h> int bind(int sockfd. Parametri: sockfd este descriptorul de socket my_addr este un pointer la structura ce conţine informaţii referitoare la adresă addrlen poate fi setat la valoarea sizeof(struct sockaddr) Vom prezenta un model de folosire a funcţiei bind(): #include <string. listen() pentru a plasa socket-ul în modul pasiv. connect (3 way handshake) şi gethostbyname (conectare cu un server de nume). Primitivele blocante folosite sunt accept. int addrlen). struct sockaddr *my_addr. Serverul apelează: getprotobyname() pentru a converti numele unui protocol în forma binară folosită de sockets.h> #define MYPORT 3490 main() 49 . close() pentru a închide socket-ul.h> #include <sys/types. apoi în buclă. close() pentru a închide noul socket.h> #include <sys/socket.

serverul va trebui să aştepte viitoarele conexiuni de la diverşi clienţi şi să le rezolve cererile. sizeof (struct sockaddr)) . Parametri: sockfd este descriptorul de socket... } După ataşarea portului. // iniţializare cu 0 a structurii bind(sockfd... .. sockfd = socket(AF_INET. 8).s_addr = inet_addr("10.57").. 0)...12.sin_port = htons(MYPORT). addrlen stochează lungimea acestei structuri.. Pentru aceasta se utilizează primitiva listen() urmată apoi de accept().Comunicaţie client-server la nivel de socket { int sockfd. Acest nou descriptor va putea fi folosit pentru a trimite şi recepţiona date via reţea prin mijlocitori precum send() sau write() şi recv() sau read(). Apelul va returna un descriptor de socket corespunzător clientului a cărui conexiune a fost acceptată. // big endian my_addr. Primitiva listen() are următoarea formă: int listen(int sockfd... struct sockaddr_in my_addr. '\0'. (struct sockaddr *)&my_addr.. backlog reprezintă numărul maxim de conecţii permise în coada de aşteptare. int backlog). // little endian my_addr. SOCK_STREAM.110. Primitiva accept() permite acceptarea propriu-zisă a conexiunilor: int accept(int sockd.sin_zero). 50 . stabilindu-se astfel un canal de comunicaţie duplex între server şi client. socklen_t *addrlen). Parametri: sockfd este descriptorul de socket addr va conţine informaţii despre adresa IP şi portul folosite de clientul conectat la server.. struct sockaddr *addr.sin_family = AF_INET.sin_addr. memset(&(my_addr.. my_addr...

opt poate lua valorile: 0 (interzice orice recepţie ulterioară). Astfel se va bloca orice read() or write() ulterior. msg reprezintă o zonă de memorie în care se vor copia datele recepţionate. este returnat -l. Primitivele close() şi shutdown() Primitiva close() va închide conecţia aferentă descriptorului de socket. Valoarea returnată este numărul de octeţi primiţi în caz de succes. 1 (interzice orice trimitere ulterioară). care uneori diferă de numărul de octeţi ce dorim să-i transmitem. Primitiva shutdown() permite un control superior al procesului de închidere a socketurilor. Parametri: sockfd este descriptorul pentru socketul ce trebuie închis. int len. 2 (interzice atât recepţia. Parametri: sockfd este descriptorul de socket. Funcţia are forma: int shutdown(int sockfd. Dacă eşuează. flags este de obicei 0 sau setat la valoarea MSG_PEEK. int opt). dacă datele recepţionate trebuie reţinute şi după ce sunt recepţionate. iar errno descrie eroarea. similar cu close()) 51 . int len. Valoarea returnată este numărul de octeţi trimişi în caz de succes. iar errno descrie eroarea. int recv (int sockfd. este returnat -l. const void *msg.Reţele de calculatoare Primitiva send() întoarce numărul de octeţi transmişi. void *buf. cel ce va încerca acest lucru va primi mesaj de eroare. unsigned int flags). Dacă eşuează. len reprezintă mărimea acestor date în octeţi. int send(int sockfd. cât şi trimiterea. int flags) Parametri: sockfd este descriptorul de socket msg reprezintă o zonă de memorie în care se află datele ce trebuie trimise len reprezintă lungimea datelor în octeţi flags este de obicei setat pe 0 Primitiva recv() întoarce numărul de octeţi recepţionaţi.

int len. const struct sockaddr *to. Sunt procesate cererile clientului prin schimbul de mesaje între server şi client (sendto() şi recvfrom()). Se ataşează socketul la port (bind()). unsigned int flags. 6. int tolen). Pot fi utilizate şi primitivele generale send() şi recv(). socket() socket() bind() bind() cerere recvfrom() sendto() răspuns sendto() recvfrom() close() close() Figura 6. Primitiva sento() este folosită pentru trimiterea datagramelor.2.2 Client-server UDP/IP Mecanismul de lucru este următorul: Se crează un socket care va trata conexiunile cu clienţii. Se închide socketul client (close()). const void *msg.2 este prezentat modul de comunicaţie client-server UDP/IP. 52 .Comunicaţie client-server la nivel de socket Funcţia întoarce valoarea 0 în caz de success şi valoarea -1 în caz de eroare. întoarce numărul de octeţi trimişi şi are următorul prototip: int sendto(int sockfd.2 Comunicaţie client-server UDP/IP În figura 6. Sunt pregătite structurile de date (sockaddr_in) pentru a ataşa socketul la portul folosit de aplicaţie.

int len. serverul va păstra evidenţa numărului de clienţi care au accesat resursa şi va raporta acest număr la fiecare apel. /* SERVER TCP */ #include <sys/types.Reţele de calculatoare Parametrii funcţiei: sockfd este descriptorul de socket. În exemplu. from reprezintă un pointer la o structură de tip sockaddr şi conţine adresa de IP şi portul sursei. unsigned int flags.h> #include <errno.h> #include <sys/socket. int *fromlen). to reprezintă un pointer la o structură de tip sockaddr şi conţine adresa de IP şi portul destinaţiei. Primitiva recfrom() este folosită pentru recepţionarea datagramelor. tolen va fi iniţializat cu valoarea sizeof(struct sockaddr). void *buf.h> 53 . flags va fi iniţializat cu 0. Parametrii funcţiei: sockfd este descriptorul de socket. msg reprezintă o zonă de memorie în care se află datele ce trebuie trimise. len reprezintă lungimea datelor primite.h> #include <netinet/in.3 Exemplificări 1.h> #include <stdio. flags va fi iniţializat cu 0 len reprezintă lungimea datelor ce vor fi trimise.h> #include <netdb. msg reprezintă o zonă de memorie în care se află datele ce sunt primite. fromlen va fi iniţializat cu valoarea sizeof(struct sockaddr) 6. struct sockaddr *from. Să se construiască un server şi un client TCP/IP. întoarce numărul de octeţi recepţionaţi şi are următorul prototip: int recvfrom(int sockfd.

SOCK_STREAM. server. buffer).sin_addr. 0. argv[0]). } /*Asociază socketului o adresă de server */ memset(&server. /*AF_UNIX. } 54 . /*adresele client. char ** argv) { unsigned short port.sin_port = htons(port). /*Creeaza un socket*/ if ((s=socket(AF_INET. int s. server. exit(1). 32)) perror("Eroare la preluarea numelui serverului"). printf("Nume server: %s \n". sizeof(server)) <0) { perror("Eroare la obţinerea adresei"). /*preia informatiile despre configurarea hostului*/ if (!(srvinfo=gethostbyname(buffer))) perror("Eroare la preluarea informatiilor despre server"). exit(4). &server. port=(unsigned short) atoi(argv[1]). 0)) <0) { perror("Eroare la creare socket"). AF_INET*/ server. /* adresa Internet locala */ if ( bind ( s. if(argc!= 2) { printf("Apel: %s port \n". server*/ struct hostent * srvinfo. namelen.34.s_addr = inet_addr("193.sin_family = AF_INET.61"). struct sockaddr_in client. sizeof(server)). /* portul client */ char buffer[32]. rc. ns.Comunicaţie client-server la nivel de socket main(int argc. exit(3). } /*preia numele calculatorului local */ if(gethostname(buffer. server.226.

} /* Creează un descriptor de socket pentru. buffer. va prelua maxim 5 cereri de conexiune de la clienţi. strlen(buffer). close(s). if ((ns = accept( s. buffer. 32. restul fiind refuzate */ if (listen(s. } /* Afişează mesajul primit de la client */ printf("Mesaj recepţionat de la client. } 55 . exit(5). /* închide sesiunea TCP/IP */ close(ns). exit(7). exit(6). &client. exit(8).Reţele de calculatoare /*Creează coadă pentru cererile de conexiune. comunicaţia serverclient */ namelen = sizeof(client). exit(0). 0) <0) { perror("Eroare la transmisie"). buffer). pe TCP: %s\n". &namelen)) == -1) { perror("Eroare la acceptarea conexiunii"). } /* Recepţionează mesajul de la client */ if(recv(ns. /*Trasmite confirmarea clientului */ if (send(ns. } endhostent(). 5) != 0) { perror("Eroare la obţinerea cozii de cereri"). 0) == -1) { perror ("Eroare la recepţie").

sin_family = AF_INET. argv[0])..h> #include <netinet/in.61"). /*informaţii server */ int s. } /*preia numele calculatorului local */ if (!(hostnm=(struct hostent *) gethostbyname(argv[1]))) { perror("Eroare la preluarea numelui serverului").s_addr = inet_addr("193.h> #include <sys/types. port = (unsigned short)atoi(argv[2]).h> #include <netdb.sin_port = htons(port).Comunicaţie client-server la nivel de socket /* CLIENT TCP */ #include <stdio. /*adresă server*/ struct hostent * hostnm.h> #include <errno. struct sockaddr_in server. exit(3).sin_addr.34.. } printf("A preluat numele de server. \n"). /*AF_UNIX. /* aceeaşi ca la server */ 56 . /*preia informaţiile despre server*/ server.. "Mesaj transferat prin socket. char ** argv) { unsigned short port. server.h> main (int argc. exit(1). pe TCP").h> #include <sys/socket. if (argc != 3) { printf("Apel: %s hostname port \n". strcpy(buffer. AF_INET*/ server. rc. /* portul client. acelaşi ca cel specificat în modulul server */ char buffer[32].226.

exit(7).\n")..... exit(5). exit(6)..\n"). buffer. } printf("A transmis mesajul.. despre server.. \n")..Reţele de calculatoare printf("A preluat inf.. /* Transmite mesajul serverului */ if (send(s. 0) < 0) { perror("Eroare la recepţie"). 0) < 0) { perror("Eroare la transmisie")... if ((s = socket(AF_INET. exit(4). exit(0). &server. strlen(buffer)... } printf("Confirmarea de la server a fost făcută. 32. sizeof(server)) < 0) { perror("Eroare la obţinerea conexiunii")..SOCK_STREAM. } printf("A creat socket-ul.\n"). close(s).\n"). buffer...0)) < 0) { perror("Eroare la creare socket"). } 57 . if (connect(s. /* Confirmare de la server */ if (recv(s. } printf("A realizat conexiunea..

server.. exit(2). server. exit(1).sin_family = AF_INET.\n").Comunicaţie client-server la nivel de socket 2.. &namelen)) 58 . /* orice port */ server.sin_port = 0. /*Asociază socketului o adresă de server */ memset(&server. &server.h> #include <netdb. if (getsockname(s. struct sockaddr_in client. server*/ int s. /* Determină portul asignat*/ namelen = sizeof(server).. } printf("S-a alocat o adresă . SOCK_DGRAM. sizeof(server)).h> #include <stdio. /*adresele client.h> #include <sys/socket. Să se construiască o aplicaţie server şi una client care să comunice prin datagrame. (struct sockaddr *) &server.s_addr = INADDR_ANY. rc.h> main() { char buffer[32].sin_addr. 0)) <0) { perror("Eroare la creare socket").. if ( bind( s. 0. sizeof(server)) <0) { perror("Eroare la obţinerea adresei"). namelen.\n").. /*Creează un socket*/ if ((s=socket(AF_INET... AF_INET*/ server. } printf("A creat socket-ul. /*AF_UNIX.h> #include <errno. /* Modul SERVER UDP */ #include <sys/types.

h> #include <netinet/in. exit(0). exit(3). sizeof(client)) < 0) { perror ("Eroare la recepţie").Reţele de calculatoare { perror("Eroare la determinarea portului").. 0. buffer). inet_ntoa(client. /* închide sesiunea UDP/IP */ close(s).h> main(int argc. ntohs(client. \n")..sin_family == AF_INET? \Internet: %s "AF_INET":"AF_UNIX"). 32.h> #include <sys/socket. &client. } printf("A recepţionat mesajul de la client. ntohs(server. (client. endhostent ().sin_port). } printf("\n Portul asignat este: %d\n".h> #include <netdb.sin_port)).. char ** argv) { 59 . exit(4).sin_addr)).h> #include <errno. /* Recepţioneaza mesajul de la client */ if (recvfrom ( s. /* Afişează mesajul primit de la client */ printf("\n Mesajul recepţionat de la client este: %s\n". buffer. printf("Parametrii: \n Nume domeniu: %s \n \Port: %d \n Adresa \n". } /* Modul CLIENT UDP */ /* Modul CLIENT UDP */ #include <sys/types. namelen = sizeof(client).h> #include <stdio.

exit(2).226. } port=(unsigned short) atoi(argv[1]). /* portul client. if(argc!= 2) { printf("Apel: %s port \n".sin_family = AF_INET.s_addr = inet_addr("193. 0. 0)) <0) { perror("Eroare la creare socket"). struct sockaddr_in server. AF_INET*/ server. strcpy(buffer. /*preia informaţiile despre server*/ server. sizeof(server)) < 0) { perror ("Eroare la transmisie"). argv[0]). exit(1). rc.sin_port = htons(port). "Mesaj transferat prin socket. SOCK_DGRAM. } /* Transmite mesajul serverului */ if(sendto(s. strlen(buffer)+1. /*AF_UNIX.Comunicaţie client-server la nivel de socket unsigned short port.34. pe UDP"). acelaşi ca cel specificat în modulul server */ char buffer[32]. buffer.61").sin_addr. exit(3). /*adresă server*/ int s. } close(s). &server. /* aceeasi ca la server */ if ((s=socket(AF_INET. server. } 60 . exit(0).

#include <sys/types. /* eroarea returnată */ int ds. /* descriptor pentru server */ int dc.h> #include <stdlib. /* numărul de clienţi */ void semnal (int nr_semnal) /* funcţia de tratare a semnalelor */ { if (nr_semnal == SIGCHLD) { wait (NULL). Se crează astfel un proces copil care va servi un anumit client. care aşteaptă un număr N de la un client şi returnează lista numerelor prime mai mici decât N.h> #include <unistd. 61 . nr--. extern int errno. /* descriptor pentru client */ int nr = 0. /* am pierdut un client */ return. Rezolvarea servirii concurente a mai multor clienţi se va face folosind apelul fork().h> #include <string. /* numarul maxim de clienţi acceptaţi */ const int CLIENTI_MAXIM = 10.h> #include <signal.h> #include <error.h> #include <sys/socket. i altfel */ int e_prim (int i) { int k.Reţele de calculatoare 3.h> #include <netinet/in. Să se construiască o aplicaţie de tip server stream (TCP) concurent.h> /* portul folosit */ const int PORT_SERVER = 9001. } } /* întoarce 0 dacă nu e prim.

} void client () /* funcţia de tratare a clientului */ { char buffer[100]. strlen (aux))!=strlen (aux)) { shutdown (dc. 2). 2)."Eşti clientul numărul: %d\n".Comunicaţie client-server la nivel de socket for (k = 2. aux. 100) == 0) { shutdown (dc. strlen (aux))!=strlen (aux)) { shutdown (dc. if (write (dc. return 1. if (write (dc. "Număr prim: %d\n". } bzero (buffer. exit (errno). exit (errno). k. char aux[100]. am ieşit */ exit (errno).t. sprintf (aux. } sprintf (aux. 100). buffer. k++) if ((i%k) == 0) return 0. "Daţi numărul:"). 2). k++) if (e_prim (k)) { sprintf (aux. } /* din şir de caractere în întreg */ număr = atoi (buffer). k). strlen (aux))!=strlen (aux)) { shutdown (dc. aux. 2). aux. } 62 . if (write (dc. k < număr. for (k = 2. /* eroare. exit (errno). k * k <= i.nr). /* citeşte numarul sub forma de şir de caractere */ if (read (dc. int i. int numar.

addr.sin.sin_family = AF_INET. } if (signal (SIGPIPE. /* tratăm semnalele */ if (signal (SIGCHLD. 0)) == -1) { perror ("socket() ") . 5) == -1) { perror ("listen() ") . server. semnal) == SIG_ERR) { perror ("signal()") .sin_port = htons (PORT_SERVER). SIG_IGN) == SIG_ERR) { perror ("signal()"). } 63 . } /* programul principal */ int main () { struct sockaddr_in server. } /* creăm socket-ul */ if ((ds = socket (AF_INET.Reţele de calculatoare } shutdown (dc. return errno. exit (errno). SOCK_STREAM. server. } if (listen (ds. return errno. exit (errno). server. sizeof (server)). sizeof (server)) == -1) { perror ("bind()"). exit (errno). 2). } /* pregătim structurile de date */ bzero (&server. return errno.s_addr = htonl (INADDR_ANY). &server. /* ataşăm la port */ if (bind (ds.

while (1) { /* acceptăm un client */ dc = accept (ds. 2) . } /* lansăm un proces care tratează cererile clientului */ switch (fork ()) { case 0: client (). /* am ajuns la numărul maxim de clienţi? */ if (nr == CLIENTI_MAXIM) { shutdown (dc. case -1: perror ("fork()").Comunicaţie client-server la nivel de socket printf ("Aşteptăm clienţi la portul %d.. default: break. NULL. PORT_SERVER) .\n". NULL). continue.. /* a mai venit un client */ } } 64 . break. } nr++.

uşurinţa implementării. ele au rămas doar în sfera limbajelor formale. Intenţia platformei Java a fost să ofere suport pentru aplicaţiile scrise în limbajul Java şi compilate în cod de octeţi Java.NET Framework — Windows Server. Globalizarea la nivel microeconomic a activităţii a transformat treptat modelul de prelucare client-server specific primelor aplicaţii de reţea. fiind identificată prin următoarele trei componente esenţiale: un mediu de execuţie independent de limbaj optimizat pentru prelucrări distribuite — .NET şi J2EE Aplicaţiile economice vehiculează un volum mare de date care trebuie prelucrate în vedere obţinerii de informaţii necesare pentru fundamentarea procesului decizional.NET este similară platformei J2EE.NET este soluţia propusă de Microsoft pentru programarea aplicaţiilor distribuite în Internet. sistemul de operare care oferă suport pentru aplicaţiile distribuite dezvoltate pe platforma . ambele constituie o abordare structurată pentru crearea aplicaţiilor distribuite. Jython fiind doar un exemplu 65 .NET a avut în vedere asigurarea următoarelor deziderate: programarea independentă de limbaj.7 Implementarea aplicaţiilor distribuite pe platformele . Chiar dacă au existat încercări de a porta şi alte limbaje pe platforma JVM. suportul pentru standarde deschise. distribuirea prelucrărilor. un mediu de dezvoltare care oferă suport pentru mai multe limbaje de programare standardizate sau proprietate Microsoft — Visual Studio . . . cel mai simplu incluzând nivelul de acces la date.NET. robusteţea şi scalabilitatea aplicaţiilor pe ansamblu. securitatea integrată. oferind limbaje compilate în cod intermediar împreună cu o bogată colecţie de interfeţe de programare pentru dezvoltarea aplicaţiilor. facilităţi de depanare avansate.NET Framework. mentenabilitatea. Viziunea care a stat la baza iniţiativei . într-un model bazat pe niveluri de servicii. nivelul logicii aplicaţiei şi nivelul de prezentare prin care aplicaţia este accesată de către utilizatori.

sau chiar Java prin IkVm şi Mono. Enterprise 66 . pentru programarea de platformă şi în reţea..NET oferă IIS cu ASP. Visual Basic . cum sunt C#. Spre deosebire de . Linux. BeOS. permiţând dezvoltatorilor să creeze aplicaţii distribuite pe mai multe niveluri. Încă de la început Java a fost proiectată să lucreze cu un număr mare de sisteme de operare. cât şi platformă pentru dezvoltarea aplicaţiilor distribuite. C++ Managed. Perl etc. şi asta pentru că ideea platformei Java a fost mereu una simplă şi eficientă: un singur limbaj care să ruleze pe mai multe sisteme de operare. existând în prezent trei ediţii ale platformei Java: J2SE (Java 2 Standard Edition).NET oferă suport pentru mai multe limbaje de programare compilate în Microsoft Intermediate Language (MSIL).NET.Implementarea aplicaţiilor distribuite pe platformele . MacOS. J2EE (Java 2 Enterprise Edition). UNIX.NET şi J2EE didactic de portare a limbajului de scripting Python pe JVM. precum Mono şi Rotor oferind suport pentru majoritatea interfeţelor de programare din . Spre deosebire de J2EE. pentru aplicaţii de întreprindere. suportul pentru limbajele de programare. pentru dispozitive mobile.NET a fost gândită să ruleze doar pe Windows. J2EE este un set de specificaţii standardizate şi nu un produs. Paltforma . platforma . Pentru implementarea aplicaţiilor distribuite este nevoie de servere de aplicaţii pentru publicarea componentelor care înglobează logica aplicaţiei. plecând de la ideea: o singură platformă pe care pot rula mai multe limbaje. Pascal (Delphi). precum WebLogic de la BEA. Spre deosebire de J2EE. J#. J2ME (Java 2 Micro Edition). rulând în prezent pe platforme: Windows. . Firma Sun Microsystems a dezvoltat Java atât ca limbaj. existând însă încercări de portare a mediului de execuţie şi pe Linux. iPlanet şi SunONE Application Server de la Sun.NET prin intermediul căruia se pot publica şi executa servicii Web scrise în limbaje compilabile pe CRL (Common Language Runtime) în MSIL (Microsoft Intermediate Language). WebSphere Application Server de la IBM.NET se concretizează în: suportul pentru sisteme de operare.NET. Platforma J2EE dispune atât de implementări comerciale.NET. metoda de execuţie. proiectele de tip Open Source. Diferenţele fundamentale între J2EE şi .

necesită. actualmente oferită de WebMethods. cărora li s-a adăugat recent JSF (Java Server Faces). dar şi la Oracle Database Server. MSDE. Platforma J2EE dispune de Java Database Connectivity (JDBC). prin intermediul căreia se poate conecta la server Microsoft precum SQL Server 2000 (sau Yukon în curând). o tehnologie dezvoltată din ASP în sensul separării procesărilor pe server de formatarea HTML a rezultatului.NET oferă ActiveX Database Objects . PostGre SQL etc. 67 . care. Access.NET. aplicaţiile distribuite fac apel la servere de baze de date relaţionale..NET.Reţele de calculatoare Server de la Borland etc. ca şi IIS-ul. Sybase. Platform . IBM DB2. MySQL.NET. prin interfeţe de programare specifice. permiţând o mai bună încapsulare a codului în executabile binare interpretabile pe CLR. Orion sau Jetty. Pentru accesul la date.NET (ADO. precum şi la MySQL sau PostGre SQL. o tehnologie echivalentă cu ASP.NET). Acestea sunt servere de componente EJB (Enterprise Java Beans). Necesită IIS cu modul ISAPI ASPNET. În J2EE există mai multe implementări SOAP. MS Access. MS SQL Server 2000. sau Glue.dll sau Apache cu modul dedicat ASP. o interfaţă de programare pentru care există drivere de conectare la aproape orice bază de date relaţională sau sistem de fişiere. Se execută atât pe servere Web. MSDE. Pentru clienţi Web este nevoie de servere Web cu suport dedicat tehnologiilor specifice. IBM DB2.NET oferă ASP. Web Services Developement Kit (WSDK) de la Sun şi omonimul său de la IBM. precum Axis şi SOAP de la Apache. un mediu de procesare a mesajelor SOAP şi de gestiune a componentelor de serviciu. precum şi de implementări Open Source cum sunt JBoss sau JOnAs. astfel: Platforma . pentru a putea găzdui servicii Web. cât şi pe servere de aplicaţii J2EE amintite la nivelul logicii aplicaţiei. Platforma J2EE oferă două tehnologii: servlet şi JSP. incluzând Oracle Database Server. iniţial dezvoltată de The Mind Electric. cele mai folosite fiind Tomcat.

inclusiv să cheme alte proceduri. servicii de analiză integrate şi migrarea şi transformarea simplificată a datelor.1 Nivelul de acces la date 7. limbajul de programare Transact-SQL (TSQL) este interfaţa primară de programare între aplicaţie şi baza de date SQL Server. Procedurile stocate sunt disponibile pentru administrarea SQL Server şi afişarea informaţiilor despre baze de date şi utilizatori. Procedurile stocate instalate o dată cu SQL Server se numesc proceduri stocate de sistem. Procedurile stocate sunt diferite de funcţii deoarece nu pot returna valori în locul numelui lor şi nu pot fi folosite direct într-o expresie. Alte caracteristici includ capacitatea de căutare de text în bazele de date şi formate de documente cunoscute.1 Apelarea procedurilor stocate pe SQL Server Microsoft SQL Server 2000 reduce vizibil timpul necesar pentru a construi soluţii bazate pe Web. prin stocarea programelor ca proceduri stocate în SQL Server şi crearea aplicaţiilor care să execute aceste proceduri şi să proceseze rezultatele. Caracteristicile pentru a aduce pe Web aplicaţiile noi şi existente sunt incluse cu suport XML şi acces HTTP. Când se creează o aplicaţie cu SQL Server. Procedurile stocate din SQL Server sunt similare procedurilor din alte limbaje deoarece pot să: primească parametri introduşi şi să returneze valori multiple sub forma parametrilor de ieşire. Se poate folosi declaraţia EXECUTE pentru a rula o procedură stocată. Procedurile stocate sunt o colecţie de declaraţii precompilate stocate sub un nume şi procesate ca o unitate. conţină declaraţii care să îndeplinească operaţiuni în baza de date. automatizând în acelaşi timp sarcinile de gestionare şi adaptare.NET şi J2EE 7. Procedurile stocate pot fi create de o persoană 68 . auto-gestionare şi adaptare dinamică. Manipularea şi execuţia procedurilor stocate se poate realiza în două moduri: prin stocarea locală a programelor şi crearea aplicaţiilor care să trimită comezile către SQL Server şi să proceseze rezultatele.Implementarea aplicaţiilor distribuite pe platformele . SQL Server 2000 este optimizat pentru a fi folosit cu Windows 2000 şi este proiectat pentru a creşte o dată cu afacerea dumneavoastră. Avantajele folosirii procedurilor stocate în SQL Server în locul programelor Transact-SQL stocate local în sistemele client sunt: permit programarea modulară: procedura poate fi creată doar o singură dată.1. stocată în baza de date şi chemată ori de câte ori este nevoie în program. de afaceri şi de depozitare a datelor.

[getProducts]".TableMappings. clientul ADO. 4.Parameters.Reţele de calculatoare specializată în programarea bazelor de date şi pot fi modificate independent de codul sursă al programului care le foloseşte.Int.Add(new SqlParameter("@RETURN_VALUE".sqlCommand.TableMappings.Add("data1".sqlConnection. ((byte)(0)). this. "".Add("data".Connection = this. în cazul unei proceduri stocate care selectează date din mai multe tabele prin intermediul unui adapter trebuie mapate colecţiile extrase din bază peste tabelele DataSet-ului destinaţie: this. decât să se trimită sute de linii de cod pe reţea. this. this.CommandText = "dbo.ReturnValue.StoredProcedure.sqlDataAdapter. false. procedura stocată selectează datele astfel: CREATE AS SELECT SELECT SELECT SELECT RETURN PROCEDURE dbo. procedurile stocate pot fi mai rapide decât codul Transact-SQL de la client.sqlCommand. this.SelectCommand = this. DataRowVersion.sqlCommand.sqlDataAdapter.sqlCommand = new SqlCommand(). "Products").sqlDataAdapter. this. "Categories").sqlDataAdapter. Stock.sqlDataAdapter.getProducts * * * * FROM FROM FROM FROM Categories.sqlCommand. this.CommandType = CommandType. Pentru apelarea unei proceduri stocate. 69 . this. "Stock"). permit rularea mai rapidă: dacă operaţiunea cere o cantitate mare de cod Transact-SQL sau este rulat în mod repetat.TableMappings.Add("data3". null)).NET pentru SQL Server oferă obiectul SqlCommand pentru care se setează proprietatea CommandType la valoarea StoredProcedure. respectiv CommandText ca fiind numele procedurii stocate din spaţiul rolului conexiunii deschise.TableMappings. SqlDbType. "Producers"). permit reducerea traficului pe reţea: o operaţiune care cere sute de linii de cod Transact-SQL poate fi executată printr-o singură declaraţie care execută codul în cadrul unei proceduri. ((byte)(0)).Add("data2". Products. Producers.sqlCommand. ParameterDirection.Current. astfel: this. this. Ele sunt analizate şi optimizate în momentul creării lor şi versiunea in-memory a procedurii poate fi folosită după ce este executată pentru prima dată.

public String FirstName.io. int port.jdbc.getConnection( 70 . "data"). import java.sql. this. } Accesor package tutorials.storedprocedure.util. import java. ClassNotFoundException { Class. public short Version. public class Group implements Serializable { public int GroupId.SQLServerDri ver").Vector.microsoft.NET şi J2EE apelul selecţiei datelor cu ajutorul adapter-ului presupune denumirea tabelei origine ale cărei mapări duc datele în tabele ale DataSet-ului: DataSet dataSet = new DataSet(). public void open(String host.CallableStatement. import java.sql.io.sql.Connection. import java.SQLException. import java. import java. import java.sql.sqlDataAdapter. Obiecte Java package tutorials.connection = DriverManager. import java. JDBC oferă obiectul CallableStatement prin intermediul căruia se pot apela proceduri stocate.ResultSet. String database.database. public String LastName. public class Student implements Serializable { public int StudentId.ForName("com. } package tutorials.database.Fill(dataSet.storedprocedure. String password) throws SQLException. public class DataAccessor { private Connection connection.Implementarea aplicaţiilor distribuite pe platformele .Serializable.Serializable.sql.DriverManager. this. String user. public String Name.storedprocedure. public short Version.sqlserver.database.

connection.setInt(1. while(results != null && results.connection. } public Group[] getGroups() throws SQLException { Vector vector = new Vector().GroupId = results.next()) { Student student = new Student().getShort(3).getString(2).getString(2). } } 7.2 Virtualizarea accesului la baza de date Platforma . group. ResultSet results = statement.DatabaseName=" + database + ". oferind mecanisme de acces bazate pe conexiune activă sau deconectate.StudentId = results.toArray(). group.NET.getShort(4).1. } public void close() throws SQLException { this.add(student). platforma . Vector vector = new Vector().FirstName = results.executeQuery(). CallableStatement statement = this. student.Name = results.Version = results.NET permite accesul la baze de date prin interfaţa ADO.getInt(1).Reţele de calculatoare "jdbc:microsoft:sqlserver://" + host + ":" + port + ". } return (Group[]) vector. student.close().prepareCall("call GetStudentsByGroup(?)"). student.executeQuery(). } return (Student[]) vector.getInt(1). ResultSet results = statement. } public Student[] getStudentsByGroup(int groupId) throws SQLException { CallableStatement statement = this.connection. while(results != null && results. statement.User="+ user + ". vector.0 căruia i s-a 71 .getString(3). group.prepareCall("call GetGroups()").").Version = results. student.toArray(). groupId). În privinţa suportului nativ pentru conectarea la diferite servere.Password=" + password + ".next()) { Group group = new Group().LastName = results.NET oferă suport pentru SQL Server chiar de la versiunea 1.

ceea ce face imposibilă instanţierea lor pentru acelaşi tip de bază: namespace Tutorials. este totuşi posibilă definirea unei interfeţe de acces la date. string user. string password).Implementarea aplicaţiilor distribuite pe platformele . ceea ce face imposibilă legarea directă la metodele acestora. cel mai cunoscut fiind ByteFX. se defineşte o interfaţă peste ADO. void Close(). string database. Prin intermediul signaturii comune a metodelor interfeţei ADO.NET au signaturi de pachete diferite. restul serverelor fiind suportate prin intermediul provider-ilor oferiţi de diferite organizaţii.NET clasele de acces la date se găsesc în pachete diferite şi au tipuri diferite. System. } } } 72 . pe platforma . } string Database { get. restul metodelor fiind comune.DataSet ExecuteQuery(string statement.Data. implementări care fac apel la pachetele şi clasele provider-ului respectiv. pentru accesul la MySQL există mai mulţi provider-i comerciali cât şi Open Source.NET şi J2EE adăugat suportul pentru Oracle în versiunea 1. object ExecuteScalar(string statement). string table). Spre exemplu.NET care reuneşte funcţii pentru operaţiile cu baza de date.Database { internal interface IDatabaseConnection { void Open(string host. ce urmează a avea implementări specifice fiecărui provider.NET pe care fiecare clasă de acces o implementează. string Provider { get. este necesară definirea unei interfeţe deoarece clasele oferite de către provider-ii ADO.1. Pentru ca aceeaşi aplicaţie să se poată conecta la mai multe servere de baze de date este necesară virtualizarea accesului la baza de date prin implementarea unui mecanism de fabrică de obiecte care să asigure legarea implementării specifice bazei de date utilizate. Dacă în cazul punţii JDBC diferă doar protocolul de conectare în funcţie de server. int ExecuteNonQuery(string statement).

SqlClient.NET specific: Clasă de acces la SQL Server 2000 namespace Tutorials. database = " + database + ".SqlCommand(statement. this.Data.connection). } public System.ExecuteNonQuery(). string table) { System.Data. string password) { this.Data.SqlClient. table). private string database.SqlClient.SqlConnection("data source = " + host + ".connection). new System. password = " + password). this.SqlDataAdapter(statement. public SQLServerDatabaseConnection() { } public void Open(string host.SqlClient.Data.SqlConnection connection. user id = " + user + ".Data.connection.Data. } public int ExecuteNonQuery(string statement) { return new System.connection). this.ExecuteScalar().connection = new System.Data.Data. } public void Close() 73 .SqlCommand(statement.SqlClient. this.DataSet().Open().Fill(dataSet. string database.DataSet ExecuteQuery(string statement. } public object ExecuteScalar(string statement) { return new System.DataSet dataSet = new System.Database { internal class SQLServerDatabaseConnection: IDatabaseConnection { private System. string user.Reţele de calculatoare se implementează interfaţa pentru fiecare server de baze de date utilizând clasele provider-ului ADO. return dataSet.

string user. } public System.Database { internal class OracleDatabaseConnection: IDatabaseConnection { private System.OracleClient.Data. private string database. password = " + password).OracleClient. this. } } Clasă de acces la Oracle namespace Tutorials.DataSet dataSet=new System. database = " + database + ".connection = new System. string table) { System.Data.Data.OracleConnection("data source = " + host + ".connection.DataSet ExecuteQuery(string statement.database.DataSet(). } } } public string Provider { get { return "SQLServer".connection!=null) this.connection.Data.Data. string database. 74 . public OracleDatabaseConnection() { } public void Open(string host. user id = " + user + ".OracleConnection connection.Open(). string password) { this.NET şi J2EE { if(this. } } public string Database { get { return this.Implementarea aplicaţiilor distribuite pe platformele .Close().

connection).ExecuteNonQuery().connection).connection).ExecuteScalar().OracleClient. } } public string Database { get { return this.OracleCommand(statement. } public void Close() { if(this.Close(). this.Fill(dataSet.MySqlConnection connection. this.Database { internal class MySQLDatabaseConnection: IDatabaseConnection { private ByteFX.database.Data.Data. this.connection!=null) this.connection. } } } } Clasă de access la MySQL namespace Tutorials.OracleCommand(statement. } public object ExecuteScalar(string statement) { return new System. 75 . return dataSet. } public int ExecuteNonQuery(string statement) { return new System.MySqlClient.OracleDataAdapter(statement. table).OracleClient.Data.OracleClient. private string database.Reţele de calculatoare new System. } public string Provider { get { return "Oracle".Data.

string password) { this.DataSet dataSet=new System. string user.database = "+database+". this.connec tion).Data.MySqlClient.Open().Fill(dataSet. this.Data. table).user id = "+user+".password = "+password).Data.MySqlCommand(statement.MySqlClient.database = database.MySqlClient.DataSet().Data.ExecuteNonQuery().MySqlClient.NET şi J2EE public MySQLDatabaseConnection() { } public void Open(string host.Data.Data. } public string Provider { get { return "MySQL". this.ExecuteScalar(). this. return dataSet.MySqlConnection(" data source = "+host+".Close().connection = new ByteFX.Implementarea aplicaţiilor distribuite pe platformele . string database. } public int ExecuteNonQuery(string statement) { return new ByteFX.connection).Data. } public object ExecuteScalar(string statement) { return new ByteFX.MySqlDataAdapter(statement. new ByteFX.connection. } public System.this.connection. } } public string Database { get 76 .connection != null) this.string table) { System.MySqlCommand(statement.connection). } public void Close() { if(this.DataSet ExecuteQuery(string statement.

database. string password) { switch(provider) { case Providers.databaseConnection = null. case Providers.SqlServer: this.MySql: this.databaseConnection = new SQLServerDatabaseConnection().databaseConnection != null) this. string user. namespace Tutorials. break. } } se construieşte o clasă fabrică de obiecte care instanţiază implementarea interfeţei de acces la baza de date specifică unui anumit server: Clasă fabrică de conexiune la o anumită bază de date using System.databaseConnection = new MySQLDatabaseConnection(). } public System. SqlServer.Oracle: this.Open(host. break.DataSet ExecuteQuery(string statement. public void Open(Providers provider. database. string host. } if(this. password). user. case Providers. string table) { 77 .Data. MySql} public class DatabaseConnection { private IDatabaseConnection databaseConnection = null.Database { public enum Providers{Oracle.databaseConnection = new OracleDatabaseConnection().Reţele de calculatoare { } } return this.databaseConnection. default: this. string database. break.

databaseConnection != null ? this.NET în care fiecare provider oferă drivere având signaturi de pachet diferite şi deci incompatibile ca tip de dată.Close(). crearea unei conexiuni este specifică fiecărui provider prin driverul şi protocolul de acces aferente. ceea ce facilitează implementarea unei clase unice de acces la diferite baze de date. } } } } Spre deosebire de soluţia ADO. ceea ce impune definirea unei clase abstracte având o singură metodă abstractă care creează o conexiune la baza de date. restul metodelor apelând interfaţa JDBC.databaseConnection. } public void Close() { if(this. } } public string Provider { get { return this. JDBC oferă o interfaţă unitară de acces.ExecuteQuery(statement.Implementarea aplicaţiilor distribuite pe platformele . } public object ExecuteScalar(string statement) { return this.databaseConnection.databaseConnection. 78 . } public int ExecuteNonQuery(string statement) { return this.Provider : null. table) : null.databaseConnection != null.NET şi J2EE return this. Totuşi. this.databaseConnection.databaseConnection = null.databaseConnection != null ? this.databaseConnection != null) { this.ExecuteNonQuery(statement) : -1. } } public bool IsOpened { get { return this.databaseConnection != null ? this.databaseConnection.ExecuteScalar(statement) : null.databaseConnection != null ? this.

createStatement()).sql.execute(statem ent). pentru conectarea la MySQL. String password) throws java.SQLException { return(this.close(). } public boolean executeDelete(String statement) throws java. java.SQLException.lang. } public boolean executeInsert(String statement) throws java. public abstract void connect(String host. protected java.sql. spre exemplu. } public boolean executeUpdate(String statement) throws java.ResultSet executeQuery(String statement) throws java.createStatement()). String database.sql.connection. protected String password.sql.execute(statem ent). String user.connection. } public java. int port. protected int port.SQLException { return(this.createStatement()). protected String user.SQLException { return(this.connection.executeQuery(s tatement).ClassNotFoundException. } } pentru conectarea la un anumit server se extinde clasa abstractă prin implementarea metodei de conectare.SQLException { this.execute(statem ent). clasa derivată va arăta astfel: public class MySQLDatabaseConnection extends DatabaseConnection { public MySQLDatabaseConnection() { } 79 . de forma: public abstract class DatabaseConnection { protected String host.createStatement()).sql.connection.sql.Reţele de calculatoare se defineşte o clasă abstractă care va conţine metoda abstractă de conectare şi implementarea comună a metodelor de acces la date.Connection connection.connection. protected String database. public void close()throws java.sql.sql.SQLException { return(this.

sql.forName("com. int port. this.DriverManager.SQLServerDri ver"). this. String user.DriverManager. String database.database + ". } } în ambele cazuri metoda de conectare face apel la clasele punţii JDBC pentru serverul de baze de date respectiv.port = port. java. Class.port = port.ClassNotFoundException.user + "&password=" + this.sql.Implementarea aplicaţiilor distribuite pe platformele .password).connection = java.Driver").database + "?user=" + this.connection = java. String password) trows java. this.port + ".port + "/" + this.Password=" + this.lang.database = database.sqlserver. } } pentru conectarea la SQL Server clasa derivată va arăta astfel: public class SQLServerDatabaseConnection extends DatabaseConnection { public SQLServerDatabaseConnection() { } public void connect(String host.user = user.database = database. this. this.java. 80 .User=" + this.gjt.SQLException { this. astfel încât pentru deschiderea conexiunii prin JDBC este necesară plasarea claselor de acces în CLASSPATH. Class.SQLException { this. this. String database.password = password.mysql. int port. this.user + ".host = host.jdbc. this.DatabaseName=" + this.sql. this.user = user.forName("org.password = password. String password) throws java.host+ ":" + this.sql. this.password + ".").NET şi J2EE public void connect(String host. String user.mm.host = host.host + ":" + this.getConnection("jdbc:microsoft:sqlserver ://" + this.microsoft.ClassNotFoundException.getConnection("jdbc:mysql://" + this.lang.

Service { public class CustomerManager : MarshalByRefObject.Remoting.Remoting. namespace Tutorials. } } Interfaţă serviciu namespace Tutorials.Runtime. public string LastName.Remoting.Remoting.Common { [Serializable] public class Customer { public string FirstName.Runtime.NET Remoting presupune următoarele acţiuni: se defineşte interfaţa şi obiectele de serviciu într-un assembly partajat între server şi client. ICustomerManager { 81 . namespace Tutorials.Reţele de calculatoare 7.Channels.Remoting.Common { public interface ICustomerManager { Customer[] GetCustomers(). using System. } } se construieşte un proiect în care se implementează interfaţa de apel: using System.Http.1 Apelarea procedurilor la distanţă Publicarea şi apelarea unui obiect prin . using System.Runtime.2 Nivelul logicii aplicaţiei 7.Remoting. using Tutorials.2. using System. public DateTime DateOfBirth.Remoting.Channels. de forma: Obiect de serviciu using System.Common.

customers[1].Remoting.NET şi J2EE public CustomerManager() { Console. RemotingConfiguration. using System. 7. customers[0] = new Customer(). 1.FirstName = "Iulian".WriteLine("CustomerManager. ChannelServices.Runtime. customers[0]. un serviciu de platformă sau o aplicaţiei consolă de test: using System.Runtime. customers[1].Http. using System.Channels.Remoting.soap".ReadLine(). 24). WellKnownObjectMode.Remoting.RegisterChannel(channel).DateOfBirth = new DateTime(1979. 1). } } } pentru publicarea serviciului se poate opta pentru un context Web pe IIS.Channels. using Tutorials. return customers. namespace Tutorials. customers[0]. customers[1] = new Customer().Implementarea aplicaţiilor distribuite pe platformele .LastName = "Nemedi".Remoting. } public Customer[] GetCustomers() { Customer[] customers = new Customer[2].RegisterWellKnownServiceType( typeof(CustomerManager).Service.Remoting. "CustomerManager. customers[1].LastName = "Cuculescu". Console. customers[0]. } 82 .constructor: Object created").FirstName = "Dan".Server { class Server { [STAThread] static void Main(string[] args) { HttpChannel channel = new HttpChannel(1979). using System.Singleton).DateOfBirth = new DateTime(1979.Runtime.

ChannelServices.soap"). using System.Runtime.Client { class Client { [STAThread] static void Main(string[] args) { HttpChannel channel = new HttpChannel().Http. namespace Tutorials. using System. foreach(Customer customer in customers) Console.Runtime.WriteLine("Customer:\n" + "First Name:\t" + customer.ToString("dd\\.Runtime.Remoting.Common. using System.LastName + "\n" + "Day of Birth:\t" + customer.GetCustomers().FirstName + "\n" + "Last Name:\t" + customer.Remoting. ICustomerManager manager = (ICustomerManager) Activator.Channels. prin intermediul cărei apelează metodele obiectului: using System.DateOfBirth.RegisterChannel(channel).Channels.yyyy") + "\n").WriteLine("Client.Main(): Reference to CustomerManager acquired").GetObject( typeof(ICustomerManager). "http://localhost:1979/CustomerManager. Customer[] customers = manager.Remoting.MM\\.Remoting. using Tutorials. Console.Reţele de calculatoare } } clientul obţine o referinţă la obiectul la distanţă apelând activatorul canalului HTTP la serverul de obiecte. } } } 83 .Remoting.

} int[] numbers = new int[found]. for(int i = 2. j++) isNotPrime[j * i] = true. public interface IPrimeNumbers extends Remote { public int[] getPrimeNumbers(int n) throws RemoteException. import java. i++) if(isNotPrime[i] == false) { found++. return numbers. for(int j = 2. } public int[] getPrimeNumbers(int n) throws RemoteException { boolean[] isNotPrime = new boolean[n + 1]. i <= n. j * i <= n.RemoteException. i <= n . } Implementarea interfeţei de metode apelabile la distanţă package tutorials. import java. i++) if(isNotPrime[i] == false) numbers[k++] = i.remoting.NET şi J2EE Arhitectura Java pentru apelarea procedurilor la distanţă prin RMI (Remote Method Invocation): Interfaţă de metode apelabile la distanţă package tutorials.rmi.RemoteException.1. import java. import java. } } 84 .rmi. int found = 0.Remote.UnicastRemoteObject. for(int i = 2.server.Implementarea aplicaţiilor distribuite pe platformele .rmi.rmi. int k = 0.remoting. public class PrimeNumbers extends UnicastRemoteObject implements IPrimeNumbers { public PrimeNumbers() throws RemoteException { super().

int n = args. primeNumbers). Naming.rmi.remoting.setSecurityManager(new RMISecurityManager()). } catch(Exception exception) { System. } } } 85 .lookup("rmi://remoting/PrimeNumbersService").getPrimeNumbers(n).remoting. } } } Client care apelează metode ale unui obiect la distanţă package tutorials. } catch(Exception exception) { System.out.println(exception. public class Server { public static void main(String[] args) { System.out.length() > 0 ? ".parseInt(args[0]) : 1000.length. " : "") + numbers[i]. public class Client { public static void main(String[] args) { try { PrimeNumbers primeNumbers = (PrimeNumbers) Naming. import java. i++) message += (message.out.toString()).println(message).Reţele de calculatoare Server pentru obiectul ale cărui metode sunt apelabile la distanţă package tutorials.Naming. int[] numbers = primeNumbers.rebind("//remoting/PrimeNumbersServer". import java.RMISecurityManager.rmi. try { PrimeNumbers primeNumbers = new PrimeNumbers().Naming.rmi. for(int i = 0.println(exception.toString()). String message = "". import java. i < numbers. System.length == 1 ? Integer.

import java. respectiv XmlReader: Clasă C# serializată XML în mod declarativ using System.Xml.ComplexTypeServices. public class Contact implements Serializable { public String FirstName. } } Clasă Java serializată XML în mod declarativ package tutorials. using System. public String LastName.complextype.io. mecanismul poate fi implementat declarativ prin intermediul atributelor sau imperativ prin instrucţiuni care apelează un obiect de tipul XmlWriter.ComponentModel.ase.Serialization. 86 . } serviciul expune o metodă care întoarce un vector de obiecte serializate XML: Serviciu C# using System. namespace Tutorials.services.2. using System.Serializable.2 Serializarea tipurilor de date complexe pentru transportul tipurilor de date complexe este necesară serializarea / deserializarea lor XML. [XmlElement("LastName")] public string LastName.Collections. [XmlElement("Email")] public string Email.Service { [XmlRoot(Namespace = "http://aris. public String Email. using System.ro/schemas")] public class Contact { [XmlElement("FirstName")] public string FirstName.NET şi J2EE 7.Implementarea aplicaţiilor distribuite pe platformele .

contacts[0]. se copiază structura unei aplicaţii Glue generate cu ajutorul utilitarului NewApp (copiată de fapt din Glue/app-template).ro".Data.Web. contacts[1] = new Contact().Services. } #endregion [WebMethod] public Contact[] GetContacts() { Contact[] contacts = new Contact[2].Dispose(). contacts[0].FirstName = "Iulian".FirstName = "Radu".Email = "radu. using System.Diagnostics.Dispose(disposing). contacts[0]. } base. contacts[0] = new Contact().Reţele de calculatoare using System. using System.LastName = "Constantinescu".Web.Email = "iulian.WebService { public ContactService() { InitializeComponent().Services.ComplexTypeServices. contacts[1].ro/schemas")] public class ContactService : System.ro".Web. private void InitializeComponent() { } protected override void Dispose( bool disposing ) { if(disposing && components != null) { components. } } } într-un proiect Java dezvoltat cu ajutorul mediului Eclipse.nemedi@ase.LastName = "Ilie-Nemedi".ase. return contacts. se 87 . using System. namespace Tutorials. contacts[1].constantinescu@ase.Service { [WebService(Namespace = "http://aris. contacts[1]. } #region Component Designer generated code private IContainer components = null.

contacts[0].constantinescu@ase.LastName = "Constantinescu". } se implementează interfaţa prin intermediul clasei serviciului. contacts[0].complextype. contacts[0] = new Contact(). se organizează clasele într-un director sursă.Email = "iulian.complextype.Email = "radu.FirstName = "Iulian". contacts[1] = new Contact().NET şi J2EE precizează că binarele aplicaţiei vor fi depuse în calea WEBINF/classes. } } clientul .services.Implementarea aplicaţiilor distribuite pe platformele .services. namespace Tutorials. pentru a putea fi serializat XML acesta trebuie să implementeze interfaţa java. contacts[1]. se defineşte interfaţa serviciului Web: Interfaţa serviciului Java package tutorials. contacts[0]. public class ContactService implements IContactService { public Contact[] getContacts() { Contact[] contacts = new Contact[2].Serializable.nemedi@ase.LastName = "Ilie-Nemedi". return contacts.io. contacts[1]. în producţie metodele serviciului fac apel la o bază de date pentru extragerea informaţiilor: Serviciu Java package tutorials.ClientForNetService 88 . respectiv într-un pachet Java în care se defineşte un tip complex care va fi întors de metodele serviciului Web.FirstName = "Radu".ro". public interface IContactService { public Contact[] getContacts(). contacts[1].ro".NET apelează serviciul prin intermediul unui proxy care conţine clase pentru deserializarea obiectelor complexe pe baza schemei XSD extrasă din descriptorul WSDL al serviciului: Client C# using System.ComplexTypeServices.

out.ContactService(). } } } clientul Java are nevoie de o clasă pentru reprezentarea obiectului complex deserializat. clasa proxy se obţine prin apelul metodei statice electric. IContactService. i++) System.class).bind: Client Java package tutorials. for(int i = 0.bind(args[0]. pentru construirea acesteia platforma Glue Professional oferă utilitarul schema2java. apelarea din Java presupune importarea pachetelui cu definirea tipului de date complex şi a interfeţei serviciu.length.FirstName + "\n" + "\tLast Name: " + contacts[i].Registry. public class Client { public static void main(String[] args) throws RegistryException { IContactService proxy = (IContactService) Registry. i < contacts.registry.Registry.RegistryException.services.FirstName + "\n" + "\tLast Name: " + contacts[i].Reţele de calculatoare { class Client { [STAThread] static void Main(string[] args) { ContactProxy. i < contacts.registry.complextype. i++) Console.WriteLine("Contact:\n" + "\tFirst Name: " + contacts[i]. for(int i = 0. Contact[] contacts = proxy.revistry.println("Contact:\n" + "\tFirst Name: " + contacts[i].LastName + "\n" + "\tEmail: " + contacts[i].Email + "\n").GetContacts(). import electric.getContacts().Length. import electric.Contact[] contacts = new ContactProxy.LastName + "\n" + 89 .

Service { [WebService(Namespace = "http://aris. } 90 . 7. } } existenţa unor tipuri de date elementare echivalente face posibilă serializarea pe o platformă şi deserializarea pe alta a tipurilor de date complexe.Data.NET şi J2EE "\tEmail: " + contacts[i].Email + "\n").Implementarea aplicaţiilor distribuite pe platformele . permite traversarea platformei de către un obiect complex. Apelarea asincronă a unui serviciu Web presupune iniţierea apelului prin execuţia metodei Begin care înregistrează o funcţie delegat callback ce va fi apelată la obţinerea răspunsului de la metoda serviciului.Web.ase. portabilitatea unui singur tip elementar.Services. cât asincron. presupunem un serviciu Web a cărui execuţie poate dura un timp mai îndelungat. using System. using System.Web.2. în ultimă instanţă programatorul putând folosi serializarea şi deserializarea String a obiectelor.exe generează metode pentru apelarea serviciului atât în mod sincron.3 Apelarea serviciilor Web în mod asincron Utilitarul wsdl. namespace Tutorials. using System.WebService { public PrimeNumbersService() { InitializeComponent(). using System. Pentru apelarea asincronă se generează câte o pereche de metode Begin_Apel_Metodă şi End_Apel_Metodă. având o metodă care determină toate numerele prime până la un număr dat ca parametru: Serviciu C# using System. de exemplu String.ro/schemas")] public class PrimeNumbersService : System. using System.Services.ComponentModel.AsyncCallService. chiar şi în absenţa mecanismelor de serializare / deserializare ale containerelor de servicii Web. using System.Diagnostics.Collections.Web.

j * i <= n.Dispose(disposing). public interface IPrimeNumbersService { public int[] getPrimeNumbers(int n).ToArray(typeof(int)). 91 .Add(i).services. } se implementează interfaţa printr-o clasă serviciu: Serviciu Java package tutorials. i++) if(isNotPrime[i] == false) numbers. int found = 0. } } } Interfaţa serviciului Java package tutorials.asynccall. public class PrimeNumbersService implements IPrimeNumbersService { public int[] getPrimeNumbers(int n) { boolean[] isNotPrime = new boolean[n + 1]. j++) isNotPrime[j * i] = true. i <= n . for(int i = 2.asynccall.services. return (int[]) numbers. } #endregion [WebMethod] public int[] GetPrimeNumbers(int n) { bool[] isNotPrime = new bool[n + 1]. ArrayList numbers = new ArrayList(). private void InitializeComponent() { } protected override void Dispose( bool disposing ) { if(disposing && components != null) { components. i <= n. i++) if(isNotPrime[i] == false) for(int j = 2.Dispose().1. for(int i = 2. } base.Reţele de calculatoare #region Component Designer generated code private IContainer components = null.

JMS.service. for(int j = 2. public class AsyncServer { public static void main(String[] arguments) throws Exception { JMS.Registry.registry. for(int i = 0. import electric.registry.numbers = this.NET conţine o metodă care va fi apelată în mod asincron la primirea rezultatelor apelului către metoda serviciului Web: Metoda clientului C# public void LoadComplete(IAsyncResult result) { this.Implementarea aplicaţiilor distribuite pe platformele .1.services. return numbers. i++) message += (message. } int[] numbers = new int[found]. i < this. } } clientul . i++) if(isNotPrime[i] == false) { found++.Cursor = Cursors.numbers.registry. import electric.asynccall. i <= n. " : "") + 92 .EndGetPrimeNumbers(result). this.publish("PrimeNumbersService". for(int i = 2.Length. int k = 0. new PrimeNumbersService()).startup("jms:///AsyncCallService").server. i++) if(isNotPrime[i] == false) numbers[k++] = i.RegistryException. i <= n .Default. j * i <= n. Registry.NET şi J2EE for(int i = 2. import electric. } } se publică serviciul pe un context Glue prin JMS (Java Messaging Services): Aplicaţie gazdă pentru serviciu Java package tutorials. j++) isNotPrime[j * i] = true.Length > 0 ? ".Registry.jms. import electric. string message = "".

pe platforma Glue Professional clientul apelează serviciul asincron prin intermediul aceleaşi interfeţe ca şi pentru apelurile sincrone.service. public class Client { public static void main(String[] args) throws RegistryException { String url = "jms://AsyncCallService/PrimeNumbersService.services.numbers[i].LoadComplete).asynccall. null). new AsyncCallback(this. ceea ce face ca cererile să fie tratate asincron prin JMS: Client Java package tutorials. int[] numbers = proxy.Registry.registry. } } 93 . " : "") + numbers[i]. import electric. } apelul sincron al metodei serviciului este înlocuit de apelul asincron al componentei Begin corespunzătoare acesteia: this. IPrimeNumbersService. Console.out.WriteLine(message). i++) message += (message.class).NET în care clientul apela altă metodă a clasei proxy. String message = "". utilizând însă alt URL pentru serviciu.RegistryException. System. i < numbers.bind(url. import electric.wsdl". int n = args. for(int i = 0.Reţele de calculatoare this.registry.BeginGetPrimeNumbers(n.parseInt(args[0]) : 1000.getPrimeNumbers(n).ToString(). IPrimeNumbersService proxy = (IPrimeNumbersService) Registry.length() > 0 ? ".length. spre deosebire de implementarea .println(message).length == 1 ? Integer.

4 Publicarea unei componente ca serviciu Web Componentele COM+ sunt implicit apelabile la distanţă deoarece clasa MarshalByRefObject.NET şi J2EE 7. } } se implementează interfaţa de aplel prin intermediul unei componente de serviciu gestionată tranzacţional în COM+: Componentă de serviciu using System.ro/schemas")] public class Order { [XmlElement("Product". cât şi de clientul care face apelul către serviciu: extind Obiectul tranzacţiei using System. Publicarea unei componente ServicedComponent ca serviciu pe IIS presupune următoarele acţiuni: se scrie o componentă de serviciu. namespace Tutorials. 94 .ase.Common { public interface IDeliveryService { bool PlaceOrder(Order order). Namespace = "http://aris. typeof(string))] public string Product. } } Interfaţa de apel namespace Tutorials.EnterpriseServices.Serialization. [XmlElement("Quantity".Common { [XmlRoot("Order".ServicedComponents.2. typeof(int))] public int Quentity.Implementarea aplicaţiilor distribuite pe platformele . using System. spre exemplu care necesită accesul tranzacţional la o bază de date pentru a înregistra o comandă.ServicedComponents. tipurile de date şi interfaţa de apel de la distanţă trebuie organizate într-o bibliotecă referită atât de serviciu care implementează interfaţa.Xml.

ServicedComponents.Now.Required)] [JustInTimeActivation(true)] public class DeliveryService : ServicedComponent.config de forma: Descriptor Web <?xml version="1. prin intermediul căreia va putea apela metodele interfeţei serviciului: 95 .remoting> </configuration> - descriptorul Web configurează în cadrul aplicaţiei un serviciu monocanal SOAP.Ticks % 2 == 0.S ervicedComponents" objectUri="/ServicedComponents/DeliveryService. assembly-ul în care se găseşte şi adresa la care va răspunde.remoting> <application> <service> <wellknown mode="SingleCall" type="Tutorials.runtime.SOAP"/> </service> </application> </system. Common.IDeliveryService { #region IDeliveryService Members [AutoComplete] public bool PlaceOrder(Common. obţine de la activator o referinţă locală a obiectului la distanţă.DeliveryService.Order order) { return DateTime.Tutorials. clientul înregistrează un canal HTTP. precizând tipul clasei serviciu.runtime.ServicedComponents { [Transaction(TransactionOption. } #endregion } } se creează o aplicaţie Web pe IIS în care se publică binarele componentei SC împreună cu un descripor Web.0" encoding="utf-8" ?> <configuration> <system.Reţele de calculatoare namespace Tutorials.

Remoting.IDeliveryService) Activator. Common.IDeliveryService). } catch(Exception exception) { Console.Runtime. "http://localhost/ServicedComponents/DeliveryService. order.Runtime. platformele Java de servicii Web interceptează mesajele SOAP/HTTP ale clientului pe care le rutează conform descriptorilor de publicare către un anumit serviciu.Runtime."). Common.Order order = new Common.Quentity = 1. using System.WriteLine(service.Remoting. using System.Remoting. namespace Tutorials.Implementarea aplicaţiilor distribuite pe platformele .ToString()).Product = "A Product".NET şi J2EE Client pentru componeta de serviciu using System. Console. Serviciile de tip EJB sunt găzduite de un 96 . ChannelServices.Http.Client { class Client { [STAThread] static void Main(string[] args) { try { HttpChannel channel = new HttpChannel()." : "Your order has been rejected. Pentru a putea apela o componentă EJB prin intermediul protocolului SOAP.RegisterChannel(channel). order.PlaceOrder(order) ? "Your order has been placed.WriteLine(exception.Channels.Channels.IDeliveryService service = (Common.ServicedComponents.GetObject(typeof(Common.SOAP").Order(). using System. } } } } Componentele EJB găzduite de containere EJB ale serverelor de aplicaţii Java Enterprise sunt apelabile prin Remote Method Invocation (RMI).

tot în fişierul web.interfaces. De fapt.NamingContextFactory</conte xtFactory> 97 .ServletServer</servlet-class> <init-param> <param-name>httpRegistryRoot</param-name> <param-value>/</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> de asemenea.jnp.ejb.Reţele de calculatoare procesor care gestionează starea acestora. responsabil cu rutarea mesajelor SOAP către procesorul serviciului: <servlet> <servlet-name>glue-SOAP</servlet-name> <servletclass>electric. descriptorul aplicaţiei Web.http. având drept model fişierul sample.StatelessSessionBeanService</class > <args> <contextFactory>org.service. în subdirectorul services din WEB-INF se creează câte un descriptor XML pentru fiecare serviciu găzduit de aplicaţia curentă. un serviciu Web de tip EJB nu este altceva decât un client Java pentru componenta EJB găzduit pe serverul de aplicaţii care este apelat prin SOAP de către clienţii externi. fişierul web.xml. mapează metoda apelului SOAP peste metoda corespunzătoare a interfeţei Remote a componentei EJB pe care o apelează apoi prin RMI. aflat în subdirectorul de resurse WEB-INF.xml este configurat şi procesorul de servicii SOAPServletContext.xml.0'?> <service> <constructor> <class>electric.server. printre care se remarcă servlet-ul glue-SOAP. pentru o componentă EJB publicată în JBoss pe contextul ejb/Exchange se creează o aplicaţie Glue folosind utilitarul NewApp care de fapt copiază conţinutul directorului apptemplate într-un director cu numele aplicaţiei. în cazul publicării unei componente EJB ca serviciu Web fişierul descriptor are următoare formă: <?xml version='1. conţine maparea servlet-urilor contextului curent.

IExchange exchange = (IExchange) Registry.class).println("usa/japan exchange rate = " + rate). System.ejbstaff. } Client Java package tutorials. } catch(Exception exception) { System. String country2). IExchange.registry.Implementarea aplicaţiilor distribuite pe platformele .war director_aplicaţie se publică prin copiere în zona de publicare a serverului JBoss (server/default/deploy) pentru apelarea dintr-un client Java este necesară includerea unei interfeţe similare interfeţei Remote a componentei EJB: Interfaţă de apel la client package tutorials. se construieşte arhiva aplicaţiei Web folosind utilitarul jar cu comanda: jar cf nume_arhivă. public class Client { public static void main(String[] args) { try { String url = args[0]. import electric.toString()).client.Registry.NET şi J2EE <url>jnp://localhost:1099</url> <jndiName>ejb/Exchange</jndiName> <homeInterfaceName>tutorials. "japan"). contextul JNDI al componentei EJB pe serverul de aplicaţii şi interfaţa Remote de apel.println(exception.ejbstaff.client. public interface IExchange { public double getRate(String county1.interfaces.out.getRate("usa".bind(url. double rate = exchange.ejbstaff.ExchangeHome< /homeInterfaceName> </args> </constructor> </service> descriptorul precizează tipul de Bean publicat. } } } 98 .out.

public interface IExchange { public double getRate(String country1. } } 7.services. Implementarea unui serviciu virtual High-Level se declară metodele interfeţei serviciu: package tutorials.virtual. public class Client { /** @attribute System.out.war copiat în spaţiul de publicare JBoss. String country2). Această legare poate fi de nivel înalt sau de nivel scăzut.NETClient.Exchange(). Un serviciu virtual nu are ataşată o implementare statică în sensul consacrat. iar numele serviciului este numele fişierului descriptor . în timp ce legarea de nivel scăzut face apel la clasa VirtualSOAPHandler.EjbStaff. platforma Glue găzduită în JBoss livrează descriptorul WSDL la adresa: http://server:port/nume_aplicaţie/services/nume_serviciu.STAThread() */ public static void main(String[] args) { EjbService.5 Servicii Web virtuale Platforma Glue Professional permite publicarea unui descriptor WSDL pentru un serviciu Web virtual având la bază un set de interfeţe. "japan"). în schimb se oferă posibilitatea înregistrării unor clase care să trateze la momentul apelului mesajele SOAP destinate serviciului virtual.xml din subdirectorul services al directorului de resurse al aplicaţiei Web (WEBINF): Client J# package Tutorials.getRate("usa".NET se construieşte o clasă proxy prin adăugarea unei referinţe Web la descriptorul WSDL al serviciului.Exchange exchange = new EjbService. } 99 . System.Reţele de calculatoare pentru apelarea dintr-un client .wsdl unde numele aplicaţiei este numele fişierului arhivă .println("usa/japan exchange rate = " + rate). double rate = exchange. Legarea de nivel înalt utilizează clasa VirtualService.2.

registry.virtual. public class Exchange implements IExchange { public double getRate(String country1.util.server. Arhitectura serviciilor virtuale High-Level are la bază mecanismul fabricii de obiecte. String country2) { return Math.): package tutorials. import java. serviciile virtuale permit ataşarea la momentul apelului a implementării adecvate contextului cererii: package tutorials. import java. public Object invoke(Object proxy.services. import electric.reflect.random() * 100. public class ExchangePublish { 100 . în primul caz fiind nevoie de un server de aplicaţii gazdă.virtual. JBoss.lang. gen Glue sau un container pentru Glue (de exemplu Tomcat.invoke(exchange. Spre deosebire de serviciile Web obişnuite care ataşează o singură implementare unei interfeţe publicate. public class ExchangeHandler implements InvocationHandler { private IExchange exchange = new Exchange(). args).http.NET şi J2EE se oferă cel puţin o implementare pentru interfaţa serviciu. } } tratarea legării implementării concrete de interfaţa publicată nu mai are loc în descriptorul aplicaţiei sau în aplicaţia gazdă.services.Registry. Method method. import electric.Implementarea aplicaţiilor distribuite pe platformele . import electric.virtual. import electric.InvocationHandler.Context. ci într-o clasă specială care se foloseşte de mecanismul de Reflection pentru dispecerizarea apelurilor metodelor serviciului către obiectul ce-l deserveşte la momentul apelului: package tutorials. Object[] args) throws Throwable { return method. WebSphere.virtual.reflect.lang.Method. WebLogic etc.HTTP.VirtualService.service.services. } } publicarea se poate face printr-un descriptor care precizează interfaţa şi handler-ul virtual sau printr-o aplicaţie consolă gazdă ce poate fi instalată să ruleze ca serviciu de platformă.

Registry. prin legarea la URL-ul descriptorului WSDL şi conversia obiectului proxy obţinut la tipul interfeţei serviciului. import java.registry. context).ISOAPHandler pentru a răspunde apelurilor SOAP către metodele serviciului: package tutorials. import electric.class.virtual.RemoteException. import electric. prin care ulterior poate apela metodele acestuia. IExchange. System.class). VirtualService exchange = new VirtualService(IExchange.wsdl".bind(url. import electric.SOAP. import electric.virtual.ISOAPHandler.SOAP.EncodedWriter.out. } } Implementarea unui serviciu virtual Low-Level un serviciu virtual de tip Low-Level implementează interfaţa electric. import electric.services.println("usa/japan exchange rate = " + rate).services.xml.Reţele de calculatoare public static void main(String[] args) throws Exception { HTTP. Context context = new Context(). ExchangeHandler handler = new ExchangeHandler().SOAPMessage. indiferent de clasa care le implementează pe server: package tutorials. IExchange exchange = (IExchange) Registry.rmi. } } clientul apelează serviciul virtual similar apelării unuia obişnuit.SOAP.io.XPath. double rate = exchange.getRate("usa".xml. exchange. "japan").xml. public class ExchangeInvoke { public static void main(String[] args) throws Exception { String url = "http://localhost:8004/glue/exchange.startup("http://localhost:8004/glue"). import electric. handler).encoded.publish("exchange". Registry. 101 .Element.

registry. public SOAPMessage handle(SOAPMessage request. public class ExchangeSOAPPublish { public static void main(String[] args) throws Exception { HTTP.getBody(). import electric.virtual.NET şi J2EE import electric. exchange). } } publicarea presupune înregistrarea interfeţei şi a handler-elor aferente.Registry. SOAPHandler). SecurityException { String arg0 = request.virtual. "http://tempuri. Math. "getRateResponse").services. result. EncodedWriter writer = new EncodedWriter(result). invokeHandler.http.setName("n".getElement(country1).addElement().VirtualSOAPHandler.SOAP. SOAPMessage response = new SOAPMessage(). import electric.publish("exchange".startup("http://localhost:8004/glue").getString(). import electric. result.util. writer.getBody().setNamespace("n".org/examples.HTTP.getString().server. String arg1 = request. static final XPath country2 = new XPath("getRate/[2]"). Element result = body.random() * 100). ExchangeHandler invokeHandler = new ExchangeHandler().getElement(country2).addBody(). ExchangeSOAPHandler SOAPHandler = new ExchangeSOAPHandler().writeDouble("Result". dintre care esenţial este cel care tratează mesajele SOAP şi prin intermediul căruia răspunde de fapt serviciul: package tutorials. VirtualSOAPHandler exchange = new VirtualSOAPHandler(IExchange. return response. } } 102 .IExchange"). Context context) throws RemoteException.Context.publish. public class ExchangeSOAPHandler implements ISOAPHandler { static final XPath country1 = new XPath("getRate/[1]").class.Implementarea aplicaţiilor distribuite pe platformele . Registry. Element body = response.

passport. De exemplu. Etapele autentificării de tip antete SOAP personalizate: crearea unui antet SOAP prin derivarea unei clase din SOAPHeader conţinând credenţiale criptate. Dacă nu sunt stocate în cache-ul aplicaţiei informaţii despre rolul utilizatorului. clientul neştiind detaliile implementării serviciului. adică verificarea identităţii utilizatorului. Pe platforma .NET: introduce două noi mecanisme de autentificare: Forms: dezvoltatorul creează o pagină prin care se cere utilizatorului să-şi introducă informaţiile de identificare.com Antete SOAP personalizate: prin care dezvoltatorul îşi implementează propriul mecanism de autentificare. tratarea evenimentului Custom Authentification în Global.config a unui modul HTTP care să implementeze metoda Init şi evenimentele Register ale interfeţei IHttpModule.Reţele de calculatoare apelarea unui serviciu virtual de tip Low-Level este similară apelării oricărui serviciu Web XML. pentru detalii despre cum anume se poate implementa acest mecanism de autentificare vezi www.asax verificându-se dacă informaţiile de autorizarea accesului nu există deja în colecţia Context. Passport: autentificarea utilizatorului se face cu ajutorul unei terţe părţi. crearea şi înregistrarea în web. Pe baza unei proceduri de validare a datelor introduse se decide dacă este autentificat sau nu.NET avem trei categorii de autentificări. categorii dictate de cine anume implementează mecanismul de autentificare: IIS: Internet Information Server oferă următoare tipuri de autentificări: Anonymous Basic Authentification Digest Authentification Integrated Windows Authentification (NTLM sau Kerberos) ASP. informaţiile despre utilizator să fie trimise sub formă de parametri la metoda serviciului web.2.Cache.6 Autentificarea şi autorizarea accesului Autentificarea presupune identificarea utilizatorului. atunci se construieşte un obiect de tip Credentials care se ataşează unui obiect de tipul Principal declarat ca utilizator curent al aplicaţiei prin încărcarea 103 . 7.

Implementarea aplicaţiilor distribuite pe platformele .xml în care se precizează tipul autentificării. Noţiunile fundamentale pentru implementarea autentificării pe platfoma GLUE sunt: Principal. Permission. Guard. Realm.jaas. Platforma GLUE oferă suport pentru autentificarea pe client şi pe server. în acest caz JAAS: <realm> <constructor> o <class>electric. o colecţie de informaţii vizând identitatea utilizatorului. Verificarea contextului de rulare al aplicaţiei se face prin intermediul atributelor PrincipalPermission asociat metodelor expuse de serviciu Web. .NET Roles.JAASRealm</class> o <args> <name>jaas</name> <config>security\jaas. colecţie de drepturi de acces asociată unei identităţi a utilizatorilor autentificaţi. Principal Permissions.User. şi anume: URL Authorization.config</config> o </args> </constructor> </realm> se editează fişierul WEB-INF/services/serviciu. GLUE include suport pentru integrarea cu standardul JAAS. rolul asociat şi permisiunile aferente. Pentru impementarea autentificării şi autorizării accesului pe platforma GLUE se au în vedere următoarele etape: se editează fişierul WEB-INF/glue-config. o constrângere care utilizează o colecţie Realm pentru a verifica că un utilizator autentificat are dreptul să execute o anumită acţiune. o acţiune care poate fi executată de un utilizator având un asociat un anumit rol. care permite autentificarea bazată pe sistemul drepturilor de acces LDAP/NT. Autorizarea presupune acordarea drepturilor corespunzătoare rolului jucat de fiecare utilizator autentificat în sistem şi vizează mai multe niveluri de acces la resurse. În varianta Professional. Role.security. fiind compatibilă cu majoritatea platformelor care utilizează autentificarea de tip HTTP.xml în care se specifică publicarea autentificării şi rolul aferent: 104 .NET şi J2EE obiectului Context. File Authorization. entitate asociată identităţii utilizatorului.

7.3.cs" AutoEventWireup="false" Inherits="Tutorials.0 Transitional//EN" > <html> <head> <title>RoomImage</title> <meta name="GENERATOR" Content="Microsoft Visual Studio .NET 7.xml în care se precizează metoda de autentificare: <login-config> <realm-name>acl</realm-name> </login-config> Pentru autentificarea apelului la un serviciu Web securizat se utilizează obiectul ProxyContext care va fi încărcat cu datele de autentificare ale utilizatorului declarat în fişierele de configurare.com/intellisense/ie5"> </head> <body MS_POSITIONING="GridLayout"> <form id="ImageForm" method="post" runat="server"> </form> </body> </html> 105 .3 Nivelul de prezentare 7.1"> <meta name="CODE_LANGUAGE" Content="C#"> <meta name=vs_defaultClientScript content="JavaScript"> <meta name=vs_targetSchema content="http://schemas. Pagină ASP.NET Pentru exemplificare vom considera o pagină ASP. context. context).aspx.Reţele de calculatoare <publish>yes</publish> <role>denumire_rol</role> se editează fişierul WEB-INF/web.RoomImage" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.setAuthPassword("parolă").class.NET care afişează ca rezultat o imagine extrasă dintr-o bază de date şi primită de la un serviciu Web sub forma unui vector de octeţi. context.bind(ur_wsdll.microsoft. ISample sample = (ISample) Registry.AspNet.setAuthUser("denumire_rol"). astfel: ProxyContext context = new ProxyContext().1 Construirea unei imagini într-o pagină ASP. ISample.NET cu Code Behind <%@ Page language="c#" Codebehind="RoomImage.

Web. if(image == null) { FileStream fileStream = new FileStream(this.WebControls.MapPath("tmp/admin_no_image. Session.jpg")).UI. fileStream.Data. using System.Read(image.Open).Parse(this. în acest caz funcţia Page_Load. using System.Server. using System.Server. Clasa paginii using System.Web.Web. Administrator.Page { private void Page_Load(object sender. image.Web. } 106 .NET şi J2EE o pagină Web extinde clasa System.ComponentModel.jpg").SessionState. using System. namespace Tutorials.MapPath("tmp/admin_no_image.Length).AspNet { public class RoomImage : System.UI. using System. using System.UI.AdministratorService service = new Administrator. are acces la interfaţa server-ului Web prin obiecte de forma Request. System. fileStream. using System.Page. Context etc. using System.Response.EventArgs e) { if(this.GetRoomImageData(int.Request["RoomId"])).Close().HtmlControls. FileMode.AdministratorService(). image = new byte[new FileInfo(this.Request["RoomId"]!=null) { this. punctul de intrare în program este handler-ului evenimentului Load al paginii.UI. Response.Drawing. byte[] image = service.Implementarea aplicaţiilor distribuite pe platformele . using System.Web.UI.Web. using System.Length ]. 0.IO.ContentType = "image/jpg".Web.Collections.

Length).. astfel încât un servlet nu separă procesările şi conţinutul rezultat de formatarea acestuia.Write(image. import java. } private void InitializeComponent() { this. image. precum şi de securitate.EventHandler(this. dacă se utilizează un mediu de construire a arhivei . } } #region Web Form Designer generated code override protected void OnInit(EventArgs e) { InitializeComponent().Reţele de calculatoare this.Load += new System.io. având următoarele caracteristici funcţionale: pune la dispoziţia programatorului obiecte pentru accesarea interfeţei server-ului Web cum ar fi HttpServletRequest.PrintWriter.servlet. servletului i se asociază un URL prin intermediul fişierului de configurare web.IOException. import java. HttpServletResponse etc. pentru a putea fi accesat.OnInit(e). 0.xml sau cu ajutorul meta-tag-ului comentariu @web.servlet-mapping. 107 .servlet şi javax.http. Servlet care accesează o componentă EJB package tutorial.OutputStream. organizate în pachetele javax.2 Apelarea unei componente dintr-un servlet Tehnologia Servlet a fost gândită să suplinească deficienţele arhitectuiri CGI legate de gestiunea proceselor şi firelor de execuţie. } #endregion } } 7. binarele unui servlet trebuie publicate în subdirectorul WEBINF/classes al unui context Web.Page_Load).io.3.Response.web.war cum ar fi Ant sau XDoclet. base. răspunsul generat la ieşire devine sursa paginii HTML.

interfaces.rmi.InitialContext. public ComputeServlet() { super().narrow(ref. HttpServletResponse response) throws ServletException.interfaces.FiboHome" * remote="tutorial.servlet. import javax.servlet.interfaces. home = (FiboHome) PortableRemoteObject.http. import tutorial. FiboHome. Object ref = context.servlet name="Compute" display-name="Computation Servlet" * description="Servlet that compute Fibonacci suite" * * @web.ServletConfig.PortableRemoteObject. import javax. import javax. } } protected void doPost(HttpServletRequest request.ejb-ref name="ejb/Fibo" type="Session" * home="tutorial.HttpServletResponse.FiboHome.servlet-mapping url-pattern="/Compute" * * @web.ServletException.Fibo" description="Reference to the * Fibo EJB" * * @jboss. } public void init(ServletConfig config) throws ServletException { try { Context context = new InitialContext().HttpServlet. import javax.Implementarea aplicaţiilor distribuite pe platformele .lookup("java:/comp/env/ejb/Fibo"). import javax.Fibo.naming. import javax. import tutorial.servlet.HttpServletRequest.ejb-ref-jndi ref-name="ejb/Fibo" jndiname="ejb/Fibo" */ public class ComputeServlet extends HttpServlet { private FiboHome home. import javax.naming.Context.NET şi J2EE import javax.servlet. /** * @web.http.class).http. } catch (Exception e) { throw new ServletException("Lookup of java:/comp/env/ failed").interfaces.servlet. IOException { 108 .

out.println("</body></html>").compute(limit).println("</title></head>"). out.println(" : "). out. } out. out.println("Fibonaci Computation"). out. e. bean. } catch (Exception e) { } } double[] result = bean. out. out. i++) { out. out.println("<p>").getParameter("limit").print(limit). i < result.println("<body>").println(i).remove(). out.println("</h1>").print(" first Fibonacci numbers "). if (value != null) { try { limit = Integer. out. for (int i = 0. } catch(Exception e) { out. out.println("<html><head><title>").Reţele de calculatoare response.print("The "). int limit = 0. out. } finally { out.setContentType("text/html").println("<br>").create().close().println("<h1>"). out.getWriter(). out. out.printStackTrace(out). PrintWriter out = response.getMessage()). String value = request.println("Fibonaci Computation").length.println(result[i]). try { Fibo bean = home.println("</p>").parseInt(value). } } } 109 .println(e.

prin care se generează conţinutul JSP. 110 . Principiul separării procesărilor de formatarea rezultatelor este cel mai bine exemplificat în standarduol JSP 2. fără imbricări de tip corp de tag. care este apoi compilat în cod de octeţi şi interpretat. pentru orice altă cerere se compară data salvării paginii JSP cu data fişierului binar generat. atributele şi handler-ele tag-urilor. extinde clasa TagSupport sau BodyTagSupport şi implementează interfaţa Tag din pachetul javax. fişierele JSP: importă biblioteca de tag-uri prin intermediul fişierului descriptor. fiind publicat împreună cu paginile JSP sau pe o anumită adresă URL dacă aparţine altui context decât cel al aplicaţiei Web curente. Implementarea handler-ului tag-ului necesită: extinderea clasei TagSupport din pachetul javax.jsp.NET şi J2EE 7.0 de tehnologia Custom Tags. la momentul primei cereri o pagină JSP este translatată într-un servlet de către serverul de aplicaţii.servlet. rescrierea metodei doStartTag. asociindu-i un prefix de tag pentru a putea utiliza tag-uri ale acesteia în codul JSP.tagext. fiind publicată în contextul aplicaţiei împreună cu celelalte clase şi componente Bean ale acesteia.tagext.jsp. având următoarele caracteristici: permite intercalarea de cod procesat pe server cu formatări HTML. verificându-se astfel dacă este necesară translatarea şi recompilarea paginii.3. se obţine o referinţă la obiectul JspWriter al fluxului de procesare a ieşirii paginii.servlet. metoda întoarce constanta SKIP_BODY în cazul unui tag simplu.Implementarea aplicaţiilor distribuite pe platformele . Pentru implementarea unui Custom Tag este necesară scrierea următoarelor componente: o clasă tag handler: reprezintă o clasă Java care precizează modul în care tag-ul produce rezultat HTML.3 Definirea unui Custom Tag în JSP Tehnologia JSP a fost dezvoltată din Servlet cu scopul separării prelucrărilor şi conţinutului de formatarea rezultatelor. un fişier descriptor al bibliotecii de tag-uri: descrie în format XML numele.

io.length)). import javax. } } Se scrie apoi descriptorul XML al bibliotecii de tag-uri custom.JspWriter. public int doStartTag() { try { JspWriter out = this.customtags. nodul info conţine o scurtă descriere a tag-ului curent.util. public class SimpleRandomTag extends TagSupport { protected int length.out. atfel: după antetul documentului XML cu DOCTYPE.IOException. Custom Tag fără imbricare package tutorials. Inc.servlet. import java.//DTD JSP Tag Library 1.sun.nextInt(this. nodul tagclass indică numele clasei handler calificat cu pachetul acesteia. import java. out. Descriptor pentru biblioteca de tag-uri custom <?xml version="1. } catch(IOException exception) { System.com/j2ee/dtds/web-jsptaglibrary_1_1. import javax.jsp. } return SKIP_BODY.print(new Random().getOut().0" encoding="ISO-8859-1" ?> <!DOCTYPE taglib PUBLIC "-//Sun Microsystems.pageContext. nodul name precizează numele tag-ului curent.tagext.TagSupport. tag-ul rădăcină este taglib. fiecare tag este definit de elementul tag precizând numele tag-ului şi handler-ul care-l tratează.dtd"> <taglib> <tag> <name>simpleRandom</name> 111 .println(exception.toString()).1//EN" "http://java.Random.servlet. generând apoi răspuns HTML prin execuţie pentru fiecare cerere în parte.Reţele de calculatoare codul este translatat în servlet la momentul primei cereri a paginii JSP.jsp.

org/TR/xhtml1/DTD/xhtml1-transitional.customtags.tld" prefix="mytags" %> <html> <head> <title>JSP Page</title> </head> <body bgcolor="#FFFFFF"> <mytags:simpleRandom/> </body> </html> Acest mecanism poate fi extins sub forma unui custom tag cu atribute şi conţinut: se declară în handler-ul tag-ului proprietăţi pentru fiecare atribut al său.NET şi J2EE <tagclass>tutorials.Implementarea aplicaţiilor distribuite pe platformele .SimpleRandomTag</tagclass> <info>Outputs a random integer.tld" prefix="customjsp" %> se defineşte un prefix asociat bibliotecii importate <prefix:tagName /> se apelează tag-uri din bibliotecă prefixate corespunzător importului <customjsp:simpleRandom /> Pagină JSP care utilizează un Custom Tag <%@page contentType="text/html" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.w3.0 Transitional//EN" "http://www.dtd"> <%@ taglib uri="/WEB-INF/jsp/CustomTags. setarea unui atribut în cadrul tag-ului echivalează cu apelarea metodei setter a obiectului handler.</info> </tag> </taglib> Utilizarea unui tag dintr-o bibliotecă într-o pagină JSP presupune: se importă biblioteca de tag-uri precizând locaţia acesteia relativă la contextul aplicaţiei sau absolută: <%@ taglib uri="customjsp-taglib. se declară atributul în descriptorul tag-ului 112 .

majoritatea companiilor combină tehnologiile.customtags. Deşi din raţiuni de compatibilitate şi integrare am fi tentaţi să optăm pentru o soluţie omogenă când se pune problema implementării unui sistem de întreprindere.Reţele de calculatoare Custom Tag care extinde un tag simplu prin adăugarea unui atribut package tutorials. ca rezultat. 113 . } } Descriptor pentru un Custom Tag cu atribute <tag> <name>random</name> <tagclass>tutorials.RandomTag</tagclass> <attribute> <name>length</name> <required>false</required> <rtexprvalue>false</rtexprvalue> </attribute> </tag> 7. specificul aplicaţiei trebuie avut în vedere la alegerea unei platforme.4 Interoperabilitatea platformelor .NET şi J2EE. Interoperabilitatea celor două platforme este necesară din următoarele considerente practice: eterogenitatea platformelor hardware şi software existente în mediul de întreprindere.NET şi J2EE Pe piaţa platformelor software pentru aplicaţii distribuite de întreprindere există în prezent două mari clase consacrate: . la baza oricărui demers de combinare a platformelor software stă satisfacerea nevoilor clienţilor într-o măsură cât mai mare.customtags. totuşi teoria avantajului comparativ evidenţiază necesitatea cooperării celor mai bune tehnologii pentru fiecare nivel în parte. public class RandomTag extends SimpleRandomTag { public void setLength(int length) { this. controlul total este ineficient.length = length.

NET precum şi dependenţa de versiunea obiectelor. folosită de majoritatea utilizatorilor finali ai produselor informatice de întreprindere. pe de altă parte. având un grad înalt de scalabilitate. oferă suport extins pentru dispozitive mobile şi protocoale dedicate gen WAP. Se pot imagina trei scenarii de interoperabilitate plauzibile: punte RMI – . soluţia J2EE este potrivită pentru nivelurile logicii aplicaţiei şi de acces la date.NET Remoting: are drept principal avantaj performanţa ridicată a comunicaţiei. având drept atuuri: interfaţa client adaptată şi optimizată pentru platforma Windows.NET este mai bună pe partea de client. ca dezavantaje se remarcă complexitatea ridicată. Această abordare nu este întotdeauna cea optimă. proprietatea obiectelor COM+ pe platforma . 114 . apelul prin cozi de mesaje: prezintă avantajul cuplării slabe.NET şi J2EE Potrivit percepţiei comune o aplicaţie eterogenă care se bazează pe cele două platforme ar trebui să folosească tehnologii . unele chiar împachetate binar şi arhivate. putând utiliza o gamă foarte largă de protocoale peste TCP.NET.NET pe partea de client şi tehnologii J2EE pe partea de server. are un raport calitate / preţ superior. deoarece: oferă o performanţă ridicată. în condiţiile existenţei unui suport extins pentru tranzacţii şi securitate. oferind soluţii fiabile. introducându-se penalizări temporare semnificative pentru sincronizare. alături de posibile neajunsuri de acces pe porturi prin Firewall.Implementarea aplicaţiilor distribuite pe platformele . necesitând convertoare de protocol. este mai mentenabilă decât . deoarece: soluţia . se integrează cu suita de aplicaţii Office. permiţând comunicarea intra şi inter-niveluri. ca principal dezavantaj se înscrie absenţa operaţiilor sincrone.

.

...................................IP .................. hiperlegătură..................... URL................................................ Adresare IP ........................................................................................IP .......................................... 1....3........ Clase de adrese .............................................................. Exemplificări ..2............ Protocolul HTTP (Hypertext Transfer Protocol) ...............................................................2.....................1........ Comunicaţie client – server TCP ...................IP ..................................................... Hipertext..................................................................................................................................................... Testarea unei configuraţii TCP .............................................................................................................. 6.............. 4...................................NET şi .. Exerciţii IIS .......... Comunicaţie client – server UDP ......................... 1............................................................. Exerciţii NCSA..................... 7........................... 3................4............................ Exemple de folosire a unor utilitare TCP ..........2..... 2................. 6............................................................... 3............ 4...................................................................................................................... 6.................................................................................................................................................. 2..................................... 3......6.. Client FTP .................... IIS ............. 2.................. 3........................ 6............................................1........................ FTP şi poşta electronică ........................1....... 3.......... Utilitare TCP .......................... Interfaţa socket ............. Exerciţii rezolvate .................... NCSA ........................1..................................3................................... Serviciul de poştă electronică – e-mail .................................................... 5..... 2....... 5................................................... Introducere .........4........................................2..................................2... 4........ 3................server ................ hipermedia .......2............5............................2... Apache .............IP .................1.............................. 2.......................................... 3...........................IP .........1.......... Introducere ...... Scheme URL ................................... Apache ... Servere WEB ....... Server FTP .............IP .......3................... 4... 1.................................... Comunicare client – server la nivel de socket .................................................... Utilitare TCP ............1..................................................................................................................1............................. Serviciul FTP – transfer de fişiere ....3..................................... 6.........................1.............................................. Implementarea aplicaţiilor distribuite pe platformele ......... 1........................2... 6...........................................2.....................................................................1.........Cuprins 4 5 6 8 9 10 10 10 11 12 18 19 19 19 21 22 26 27 30 30 33 34 35 35 39 43 43 44 48 52 53 65 1...................................................................... Introducere .......................................... Modelul client .................................... 5.........3....................................................... 2.......................................................................................................2............................................ Exerciţii .................

...............5..................... 7.......1....................... Definirea unui Custom Tag în JSP .. 7. 7........ Bibliografie ...........2................................................................... 7..................... Servicii WEB virtuale ..........4...................................................... Publicarea unei componente ca serviciu WEB ........ 86 90 94 99 103 105 105 107 110 113 116 .......................... 7.........6...... 7....................... 7...................2.......................... 7...... Interoperabilitatea platformelor ...............7..NET ...........................3.........4.....2......3...................... Serializarea tipurilor de date complexe ........3......... Construirea unei imagini într-o pagină ASP.........NET şi J2EE ..3................................................................ Apelarea unei componente dintr-un servlet .......................2............ 7......... Apelarea serviciilor WEB în mod asincron ...........................................3........................................2....2.......................................................2..................... Autentificarea şi autorizarea accesului ............. Nivelul de prezentare ......3.............

până în prezent are totuşi dezavantajul implementării parţiale a standardelor pentru securitate. Dezvoltarea modelului GXA (Global XML Web Services Architecture) intenţionează să înlăture aceste neajunsuri prin protocoale de tipul WS-Security.Reţele de calculatoare servicii Web: se remarcă drept varianta optimă de interoperabilitate pentru cele mai multe situaţii datorită cuplării slabe. WS-Attachement sau WS-Routing. dar mai ales pentru tranzacţii. cât şi asincrone. în condiţiile executării de operaţii sincrone. 115 . fără restricţii de tip Firewall sau conversii de protocoale de comunicaţie.

J. 8. Practical J2EE Application Architecture.. McGraw-Hill. R. 116 .NET Remoting.. 10. KAPLAN. CIOBANU. Editura Econmică. F. RAMMER. WILLIAMS. Programarea reţelelor de calculatoare.Bibliografie 1. NAFTEL. PUVVALA. POTA. A. 2. 5. CRAWFORD W. Editura de Vest. Iaşi. 2004. S. 9. Editura Polirom. GANESHAN. 2001. 2003. 11. Timişoara.. 7. P. NĂSTASE. JURCA. GULZAR. O’Reilly. 6. PELTZER.. Addison Wesley. Advanced .NET Remoting. 3. BURAGA. MS Press. I. 2002. Atelier de programare în reţelele de calculatoare. I. 2003. F. D. K.. 2002. N. . Tehnologia aplicaţiilor WEB. NĂSTASE. 003. K. J. Addison-Wesley. 2003. MCLEAN.. Bucureşti. Bucureşti.NET & J2EE Interoperability. Arhitectura reţelelor de calculatoare. 2003. McGraw-Hill. MONSON-HAEFEL. J.NET for Java Developers: Migrating to C#. Editura Economică. 1998 . . S. 4. APress. 2001. J2EE Web Services. G. J2EE Design Patterns. NĂSTASE.

ŢĂPUŞ.com MySQL: MySQL Server. V. Sun Microsystems. 2003.go-mono. Baze de date pentru comerţ electronic pe suport Internet. UDDI SDK..org Eclipse: Eclipse SDK – http://www. Editura Economică.org IBM: WSDK – http://www.. I. JWSDP – http://java.. I..NET Providers.sun.webmethods.NET Framework for Linux – http://www. 14.4 Tutorial. STANCIU-TIMOFTE. C. ATANASIU. J2EE. GODZA.jboss. J2EE 1. NĂSTASE. INTERNET & INTRANET . ROŞCA.ibm.com 117 . PAIU. CRISTEA.NET SDK.com JBoss: JBoss Server.. G.eclipse.. Editura Oscar Print. JDBC Drivers – http://www. Fl.com Sun: J2SDK. C. 2000.apache. * Sun Resurse Apache: Tomcat.Bibliografie 12. COSTINESCU..com WebMethods: Glue – http://www.mysql. Struts – http://www. Bucureşti.microsoft.Concepte şi aplicaţii.org Microsoft: .. B. N. ADO. MSDE – http://www. 2002. JBoss IDE for Eclipse – http://www.. 13. Bucureşti. O. STANCIU.com Mono: .

Sign up to vote on this title
UsefulNot useful