Sunteți pe pagina 1din 8

DIMA ANTONIO MVMMD Anul I

Proiect A.S.I.A.

Pentru programarea aplicatiilor n reea, .NET Framework pune la dispoziie namespace-ul System.Net. Clasele i namespace-urile cuprinse aici ofer suport pentru majoritatea protocoalelor utilizate n reele (IP, TCP, UDP, HTTP, SMTP, etc.). Versiunea 2.0, fa de cea precedent, conine clase ce permit testarea conectivitii (ping) i obinerea informaiilor despre reeaua n care este conectat calculatorul (adresa MAC, domeniul, IP-ul, gateway-ul, etc.). De asemenea a mai fost introdus i un nou namespace System.Net.Security, care conine clase ce implementeaz protocoalele de securitate SSL i Negotiate. Aceste API-uri ofer servicii de autentificare i criptare a datelor vehiculate prin reea. Pentru resurse FTP au fost introduse clasele FtpWebRequest i FtpWebResponse ce ofer funciile necesare pentru implementarea unui client de FTP. ncepnd cu .NET Framework 2.0 se pot procesa cereri HTTP n interiorul aplicaiilor managed utiliznd API-ul oferit clasa HttpListener. Acest lucru este posibil pentru sistemele care ruleaz Windows XP SP2 sau Windows Server 2003. Obinerea informaiilor despre reea n cadrul unei aplicaii distribuite ntr-o reea pot aprea situaii n care modul de funcionare trebuie modificat n funcie informaiile despre reea. De exemplu dac un server conine mai multe interfee de reea iar cea n funciune cade, aplicaia server trebuie s tie s trateze aceast situaie, pentru a nu opri deservirea clienilor. O alt situaie des ntlnit este aceea n care clientul dorete testeze conectivitatea cu serverul. Versiunea 2.0 de .NET Framework conine un nou namespace System.Net.NetworkInformation ce ofer API-uri pentru determinarea traficului de date, informaii despre reea, notificri asupra schimbrilor de adrese n reea i testarea conectivitii calculatoarelor n reea. Verificarea conectivitii Pentru verificarea conectivitii, .NET Framework 2.0 introduce clasa Ping ce ofer o funcionalitate asemntoare cu cea a utilitarului de reea ping: trimite ctre destinaie o cerere ICMP i ateapt un interval de timp rspunsul. Dac nu s-a primit feedback-ul la timp se consider c acel calculator nu poate fi accesat. De obicei pachetele ICMP sunt filtrate de routere i firewall-uri i pot mpiedica succesul operaiei de ping. Clasa Ping este proiectat urmnd modelul de programare asincron i conine metode ce permit
2

efectuarea operaiei de ping n mod blocant i neblocant: Send() i respectiv SendAsync(). Pentru fiecare instan a clasei este permis doar un singur apel la un moment dat. Dac se ncearc apelarea metodelor nainte de a ntoarce rezultatul atunci acestea vor genera o excepie. Sfritul operaiei de ping este tratat prin intermediul unui eveniment, PingCompletedEventHandler. n semntura sa exist un parametru de tip PingCompletedEventArgs prin intermediul cruia se poate prelua starea operaiei i opiunile cu care a fost trimis pachetul ICMP. Acest lucru se realizeaz prin obinerea unui obiect PingReply returnat de proprietatea PingCompletedEventArgs.Reply. Mesajul returnat de cererea ICMP pot fi determinate prin inspectarea proprietii PingReply.Status ce returneaz un obiect de tip IPStatus. nainte de a trimite vreun pachet trebuie setate cteva opiuni ce vor modela cererea ICMP. O parte din ele pot fi setate utiliznd un obiect PingOptions (timpul de via (engl. time to live) i tipul fragmentare a pachetului IP) iar altele sunt setate n momentul apelului metodei Sendxx() (timpul de ateptare, adresa IP destinaie i datele utile ale pachetului). Fiecare din ele pot fi utile atunci cnd dorim s trimitem cererea ICMP ctre o destinaie printr-o reea ce admite pachete de date cu anumite restricii legate de timpul via, fragmentare sau lungimea datelor utile. Interfaa BSD Socket n .NET Framework Clasa Socket din namespace-ul System.Net.Sockets reprezint o implementare a interfeei soclurilor Berkeley i ofer metode sincrone i asincrone de transfer a datelor. Operaiile pe un socket pot fi asemnate cu operaiile de intrare\ieire pe un fiier, socket-ul fiind asociat handleului pe fiier. Socket-urile pot fi folosite pentru a permite ca dou sau mai multor aplicaii s comunice ntre ele. Aplicaiile sunt de obicei, pe calculatoare diferite, ns pot fi i pe acelai calculator n procese sau domenii ale aplicaii diferite.

Pentru ca dou aplicaii s comunice ntre ele cu ajutorul socket-urilor, indiferent dac sunt pe acelai calculator sau pe calculatoare diferite, de obicei, o aplicaie conine o component server care ascult continuu cererile i cealalt, o aplicaie client ce iniiaz conexiuni i trimite cereri ctre aplicaia server. Aceasta din urm poate s accepte sau s resping conexiunea sau cererea. Dac aplicaia server accept conexiunea un dialog se poate stabili ntre client i server. nchiderea conexiunii poate fi realizat att de client ct i de server. Att timp ct un client are o conexiune activ acesta poate trimite date serverului sau poate primi date de la acesta. De fiecare dat cnd partenerul de comunicaie trimite date celuilalt partener se presupune c aceasta din urm recepioneaz datele respective. Acest lucru este posibil ntruct trimiterea i recepionarea sigur a pachetelor de date este realizat de protocoalele de pe nivelele inferioare ale stivei TCP\IP. Pentru partea de recepionare a datelor exist dou variante: fie aplicaia verific dac nu au sosit date la intervale regulate, fie exist un mecanism prin care aplicaia s fie informat c au sosit date. Din moment ce Windows-ul este un sistem de operare care se bazeaz pe evenimente cea mai bun opiune este cea care se bazeaz pe notificare. Aa cum am spus anterior, pentru ca cele dou aplicaii s comunice ntre ele este necesar realizarea, mai nti, a unei conexiuni. Pentru ca dou aplicaii s realizeze o conexiune, n prim faz este necesar ca s se realizeze identificarea acestora (sau a calculatoarelor pe care ruleaz). Crearea unui soclu Un soclu poate creat prin urmtoarele metode: apelarea uneia dintre variantele de constructor: Socket (SocketInformation); Socket (AddressFamily, SocketType, ProtocolType); acceptarea unei conexiuni prin apelul metodei Socket.Accept() sau utiliznd varianta asincron a acesteia; Prima variant de constructor a fost introdus n .NET Framework 2.0 i primete ca parametru un obiect SocketInformation obinut din apelul metodei Socket.DuplicateAndClose(idprocesor). Acest metod creeaz o copie a configuraiei a soclului curent i apoi l nchide. Motivul este urmtorul: apelnd de mai multe ori constructorul i folosind aceiai parametri se vor crea instane ce folosesc practic acelai socket.
4

Cea de-a doua variant necesit mai multe explicaii ntruct n funcie de parametrii constructorului vom crea un socket pentru un anumit tip de protocol care folosete o anumit schem de adrese i un anumit mod de prezentare a datelor. Primul parametru se refer la schema de adresare folosit pentru socket. Schema de adresare este diferit de la un tip de reeala alta. Cteva exemple de scheme de adresare suportate sunt: InterNetwork (IPv4 i IPv6), Irda, DecNet, IPX, AppleTalk, ATM i NetBios. Al doilea parametru determin tipul soclului i n unele cazuri i protocolul folosit. Ultimul parametru specific protocolul folosit de acel socket. Printre tipurile des folosite n aplicaiile distribuite se numr: ICMP, IP, IPv4, IPv6, IPX, SPX, TCP, UDP etc. Protocolul poate fi determinat din ceilali doi parametri ai constructorului. De exemplu pentru un socket stream protocolul va fi TCP. Conectarea la server i comunicarea inter-socket Dup ce s-a creat un socket trebuie s realizm o conexiune la server. Pentru a ne conecta la un computer din reea trebuie s tim adresa de IP i portul la care ne conectm. .NET ofer clasa IPEndPoint din cadrulnamespace-ului System.Net ce reprezint un terminal din reea printr-oadres de IP i un numr de port. Primul parametru al constructoruluitrebuie s fie o instan a clasei IPAddress iar al doilea de tip ntregreprezentnd portul de comunicaie: IPEndPoint (IPAddress address, int port); Dac examinm clasa IPAddress vom vedea c are o metod staticnumit Parse(String) de tip fabric (engl. factory method) care returneazo instan a clasei. Funcia primete ca parametrul un obiect de tip String(reprezentarea adresei IP). Al doilea parametru va fi numrul portului. O dat ce avem pregtit instan clasei IPEndPoint putem folosi metoda Connect() a clasei Socket pentru a ne conecta la acesta (calculatorul server din reea). De partea cealalt socket-ul serverului, mai nti, va fi asignat unui IP i port local prin metoda Socket.Bind(EndPoint) iar apoi va trece n starea de ascultare prin apelul Socket.Listen(lungime_coada_asteptare). Metoda Listen() trebuie apelat dup ce socket-ul a fost asignat unui
5

terminal (engl. end point) local. Acceptarea conexiunilor se face prin apelul blocant al metodei Socket.Accept(). Metoda returneaz o instan a clasei Socket pentru noua conexiune acceptat. Presupunnd c o conexiune este realizat, putem trimite date celeilalte pri utiliznd metoda Send() a clasei Socket. Metoda Send() este suprancrcat. Toate semnturile accept ori ir de octei ori o colecie compus IList<ArraySegment<byte>>. Metodele Send() i Receive() ce conin n semntur o astfel de colecie de octei vor fi discutate mai trziu. Trebuie subliniat faptul c metoda Send() este blocant. Adic firul de execuie apelant va atepta pn cnd datele au fost trimise sau o excepiea fost generat din interiorul metodei. Exist i o versiune a metodei Send() care nu realizeaz blocaje care va fi prezentat ulterior. Similar metodei Send() este metoda Receive() din clasa Socket. Metoda Receive() realizeaz de asemenea un blocaj n thread-ul curent. Acest lucru nseamn c, n cazul n care nu sunt date disponibile, apelul se va bloca pn cnd sosesc date sau este generat o excepie. Funcia Receive() are cel puin dou aspecte negative. Cnd apelm aceast funcie apelul se blocheaz, dac nu sunt prezente date, pn cnd sunt recepionate nite date. Chiar dac sunt date cnd facem apelul nu tim cnd s facem apelul urmtor i, din aceast cauz trebuie s facem verificri/sondaje (engl. polling) repetate dac au venit sau nu date, rezolvare care nu este cea mai eficient. Putem ncerca s eliminm aceste neajunsuri folosind mai multe firede execuie, adic s pornim alt fir de execuie i s l lsm pe acesta s atepte datele i s notifice firul principal de sosirea datelor. Acest concept ar putea funciona bine, ns prin crearea unui nou fir de execuie, timpul de procesor alocat firul principal va fi mprit acum ntre acesta i firul nou creat. Soluia comunicaiei neblocante este oferit de funciile asincrone pe care clasa Socket le conine. Comunicaii neblocante - clientul Clasa Socket din .Net Framework ofer metoda BeginReceive() pentrurecepionarea asincron a datelor, adic ntr-o manier ce nu creeaz blocaje. Funcia BeginReceive() nregistreaz un callback delegat care va fi apelat n momentul n care sunt recepionate date. Ultimul parametru al BeginReceive() poate fi orice clas derivat din Object, sau

poate fi specificatca i null. Functia de callback returneaz tipul void i primete un singur parametru i anume interfaa IAsyncResult. Aceasta conine starea operaiunii asincrone de primire. S presupunem c am apelat BeginReceive() i dup o perioad de timp datele au sosit i funcia callback a fost apelat. Datele sunt acum disponibile n buffer-ul pe care l-am trimis ca prim parametru n apelul BeginReceive. nainte de a accesa buffer-ul trebuie s apelm funcia EndReceive() pentru obiectul Socket.EndReceive() va returna numrul de octei primii. Accesarea buffer-ului nainte de apelul EndReceive() nu este permis. Funcia OnConnect() realizeaz o conexiune la server i apeleaz funcia WaitForData(). Aceasta din urm creeaz delegatul pentru callback i apeleaz funcia BeginReceive() trimind un buffer global i obiectul Delegate ce reprezint funcia de rspuns. Cnd datele sosesc sunt apelate funciile OnDataReceive() i EndReceive() ale socket-ului socClient care returneaz numrul de octei primii i apoi datele sunt copiate ntr-un obiect String iar apoi este fcut un nou apel pentru WaitForData() care va apela din nou BeginReceive(), amd. S presupunem c avem dou socluri ce se conecteaz fie la dou servere diferite, fie la acelai server. O modalitate simpl de realizare ar fi s crem doi delegai diferii i s i atam de obiectelor Socket prin funciile BeginReceive(). Dac am avea mai multe obiecte Socket aceast metod nu este folosit n mod eficient. O alt soluie ar fi folosirea numai unui delegat callback, ns problema ce deriv din aceasta este aceea de a ti care socket i-a ncheiat operaia de intrare\ieire. Dac analizm din nou funcia BeginReceive() ultimul parametru este un obiect de stare - de tip Object. Putem trimite orice obiect aici. Aceasta va fi returnat ulterior ca parte a parametrilor funciei callback. Mai precis, acest obiect de stare va fi trimis ulterior prin intermediul proprietii IAsyncResult.AsyncState. Acest mecanism este util ntruct n momentul n
7

care callback-ul este apelat, putem folosi aceast informaie pentru a identifica obiectul Socket care a ncheiat operaia. Din moment ce putem trimite orice acestui ultim parametru, i putem trimite un obiect care s conin informaiile specifice pentru fiecare conexiune: obiectul de tip Socket i buffer-ul de primire a datelor. Dup cum se va vedea mai departe aceast modalitate este util i n cazul serverului ce trebuie s gestioneze mai multe conexiuni n acelai timp. Un alt aspect ce merit menionat este acela al mrimii buffer-ului de primire a datelor. Atunci cnd apelm BeginReceive() trebuie s trimitem un buffer i numrul de octei pe care l primim. ntrebarea care se pune aici este ct de mare ar trebui s fie acest buffer. Mrimea optim depinde de aplicaie. Dac avem o mrime mic a buffer-ului, de exemplu 10 octei i sunt 20 octei de citit, atunci ar fi necesare 2 apeluri pentru a recepiona datele. Pe de alt parte dac specificm lungimea de 1024 i tim c, ntotdeauna vom primi date n blocuri de 10 octei vom risipi inutil memorie. Soluia cel mai des folosit n practic este crearea unui buffer a crui lungime s se modifice dinamic n funcie de datele vehiculate.

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