Capitolul 1. Introducere ………………………….. ………………………….. ………………………….. ………….. 3… [604544]

Facultatea de Automatica si Calculatoare U.P.T.
1
Cuprins
Capitolul 1. Introducere ………………………….. ………………………….. ………………………….. ………….. 3
Capitolul 2. Fundamente teoretice ………………………….. ………………………….. ……………………….. 6
2.1 Baze le Remote Method Invocation ………………………….. ………………………….. ……………… 6
2.2 Avantajele și dezavantajele tehnologiei RMI ………………………….. ………………………….. …7
2.3 Privire de ansamblu asupra arhitecturii RMI ………………………….. ………………………….. …8
2.3.1 Suroga ți și scheleți (Stubs and Skeletons) ………………………….. ………………………….. .9
2.3.2 Nivelul de referire la distan ță………………………….. ………………………….. ……………… 10
2.3.3 Nivelul transport ………………………….. ………………………….. ………………………….. ……10
2.3.4 Clientul ………………………….. ………………………….. ………………………….. ……………….. 11
2.3.5 Server -ul RMI ………………………….. ………………………….. ………………………….. ……… 12
2.3.6 Registrul RMI ………………………….. ………………………….. ………………………….. ………. 12
2.4 Interfe țele, clasele și metodele la distanț ă………………………….. ………………………….. ……13
2.4.1 Interfa ța java.rmi.Remote ………………………….. ………………………….. …………………… 13
2.4.2 Clasa RemoteException ………………………….. ………………………….. …………………….. 13
2.4.3 Clasa RemoteObject și subclasele ei ………………………….. ………………………….. ……. 14
2.5 Încărcarea dinamică a claselor ………………………….. ………………………….. ………………….. 14
2.6 Se rializarea ………………………….. ………………………….. ………………………….. ………………… 15
2.7 Manageri și polițe de securitate ………………………….. ………………………….. …………………. 17
2.7.1 Permisiuni ………………………….. ………………………….. ………………………….. ……………. 17
2.7.2 Manageri de securitate ………………………….. ………………………….. ………………………. 18
2.7.3 Poli țe de securitate ………………………….. ………………………….. ………………………….. ..18
2.8 Custom Sockets ………………………….. ………………………….. ………………………….. ………….. 19
2.9 Colectarea de șeurilor ………………………….. ………………………….. ………………………….. ……20
2.10 Componente grafice în Java ………………………….. ………………………….. ……………………. 20
2.10.1 Pachetul java.swing ………………………….. ………………………….. …………………………. 20
2.10.2 Caracteristicile componentelor grafice ………………………….. ………………………….. ..22
Capitolul 3. Specifica țiile aplicației ………………………….. ………………………….. ……………………. 23
3.1 Struct ura generală a fun ționalit ății aplicației ………………………….. ………………………….. .23
3.2 Funcționalitatea clientului și scurt ă prezentare a conceptelor jocului ………………………. 24
3.2.1 Conce ptele jocului de Poker Texas Hold’em ………………………….. …………………….. 24
3.2.2 Func ționalitatea necesar ă începerii jocului ………………………….. ……………………….. 25
3.2.3 Func ționalitatea necesar ă desfă șurării jocului ………………………….. ……………………. 25
3.3 Interfa ța grafic ă a utilizatorului ………………………….. ………………………….. …………………. 25
Capitolul 4. Proiectarea aplica ției………………………….. ………………………….. ………………………. 29
4.1 Mediul de lucru Eclipse IDE for Java EE Developers ………………………….. ………………. 29

Facultatea de Automatica si Calculatoare U.P.T.
2
4.2 Arhitectura aplica ției………………………….. ………………………….. ………………………….. ……29
4.3 Proiectare de detal iu a aplica ției………………………….. ………………………….. ………………… 29
4.3.1 Proiectarea aplica ției pe partea de server ………………………….. ………………………….. 29
4.3.2 Proiectarea aplica ției pe partea de client ………………………….. ………………………….. .30
4.3.3 Proiectarea interfe țelor la distanț ă………………………….. ………………………….. ……….. 30
Capitolul 5. Implementarea codului pe partea de server ………………………….. …………………….. 33
5.1 Clasa ServerStarter ………………………….. ………………………….. ………………………….. ……… 33
5.2 Pachetul gamelogic ………………………….. ………………………….. ………………………….. …….. 34
5.2.1 Clasa Game ………………………….. ………………………….. ………………………….. …………. 34
5.2.2 Clasa Round ………………………….. ………………………….. ………………………….. ………… 36
5.2.3 Clasele Hand și HandEvaluator ………………………….. ………………………….. …………… 37
5.2.4 Clasele Card,Deck și gamelogic.table.Table ………………………….. ……………………… 39
5.3 Pachetul player ………………………….. ………………………….. ………………………….. …………… 40
5.4 Pachetul server.rmi ………………………….. ………………………….. ………………………….. ……… 40
5.5 Comunicarea client -server prin invocarea metodelor la distan ță………………………….. …41
Capitolul 6. Implementarea codului pe partea de client ………………………….. ……………………… 43
Capitolul 7. Punerea în func țiune și cerințele speciale ………………………….. ……………………….. 45
Capitolul 8. Concluzii ………………………….. ………………………….. ………………………….. ………….. 46
Bibliografie ………………………….. ………………………….. ………………………….. …………………………. 47

Facultatea de Automatica si Calculatoare U.P.T.
3
Capitolul 1. Introducere
Aplicațiile distribuite reg ăsite pe Internet sunt dezvoltate tot mai des prin intermediul
tehnologiilor obiectelor di stribuite. Cele mai răspândite astfel de tehnologi sunt Java Remote
Method Invocation (RMI), CORBA si DCOM. Lucrarea de fa ță va prezenta o astfel de
aplicație distribuit ă bazată pe tehnologia Remote Method Invocation și va fi destinat ă jocului
in rețea de Poker de tip Texas Hold’em. Scopul proiectului este de a eviden ția importanța
aplicațiilor distribuite in zilele noastre cât și avantajele si dezavantajele tehnologiei obiectelor
distribuite de tip RMI.
Cerințele impuse de jocul in rețea de Poker sunt pe d eplin satisfăcute de structura unei
aplicații distribuite. Vom evidenția acest fapt pe baza descrierii comportamentului și structurii
acestui tip de aplica ții cât și pe baza descrierii jocului de Poker. Cerințele aplicație impun o
arhitectură three -tier, c are este o arhitectura de tip client –server, pentru a separa
implementarea logicii si administrării jocului de interfa ța grafic ă a utilizatorului și de accesul
la date(bază de date, stocarea fi șierelor). Acest tip de arhitectur ă satisface cerin ța aplicaț iei din
punct de vedere al amplasării geografice a utilizatorilor, deoarece ace știa se pot situa in
locații diferite( cl ădiri, ora șe, țari sau continente diferite). Definiția unei arhitecturi de tip
client -server este „o re țea în care fiecare calculator s au proces este ori un client ori un server.
Server -ele sunt mai performante și sunt dedicate management -ului fi șierelor,imprimantelor
sau al traficului de re țea. Clienții sunt calculatoare personale sau stații de lucru pe care
utilizatorii rulează aplica ții. Clientii se bazeaza pe server pentru resurse, cum ar fi fi șiere,
aparate sau chiar putere de procesare.”[MAL03] Astfel in arhitectura de tip client -server,
clientul solicită servicii de la server pe baza unei conven ții de comunicare. O astfel de
convenție trebuie să con țină un protocol implementat atât de client cât și de server. In
aplicația de faț ă protocolul implementat este cel specific RMI, adica Java Remote Method
Protocol (JRMP) care la rândul lui foloseste două protocoale distincte: serializarea obiectelor
si Hypertext Transfer Protocol (HTTP). Serializarea obiectelor se ocupă de punerea in stream
a apelului si de scoaterea din stream a datelor returnate. [Obe01]
Avantajele principale ale arhitecturii de tip client -server sunt:
Hardware -ul server -ului este proiectat pentru deservirea rapidă a cererilor clienților,
iar datele sunt procesate pe partea de server, reducând mult traficul de re țea intre
serverși clienți.
Cum datele importante se regasesc toate intr -o singura locatie, este facilitată efi ciența
copiilor de siguran țăși mangement -ul erorilor.
Clienții nu au acces direct la baza de date, iar astfel modific ăriile aduse bazei de date
nu afecteaza soft -ul pe partea de client, deoarece acesta isi ob ține informațiile de la
obiectele de tip bussin es din partea de server.
Toate aceste avantaje nu vin fara urmă de dezavantaje. Sistemele distribuite cu arhitectură
de tip client –server sunt foarte costisitoare, iar server -ul, in cazul unei defectări, poate duce la
căderea sistemului sau la laten țe mar i. Un ultim dezavantaj îl constituie faptul ca acest tip de
sistem necesită între ținere permanenta.
O schemă a arhitecturii de tip three -tier client -server se poate vedea in figura 1 de mai jos.
Atât clientul cât și server -ul vor fi implementa ți in limba jul orientat pe obiecte Java. Server -ul
va publica obiectele sale la distan ță si va astepta ca acestea să fie căutate de către clien ți.
Clientul este implementat sub forma unui JApplet care este foarte u șor de rulat din cadrul
oricărui browser care oferă s uport pentru Java. Utilizatorul trebuie să introducă in bara de

Facultatea de Automatica si Calculatoare U.P.T.
4
adese URL -ul la care este publicat primul obiect la distan ță al server -ului. Celelalte obiecte la
distanță necesare clientului vor fi returnate de metoda la distan ță a primului obiect.
Fig.1 Arhitectura Three -Tier
Aplicația distribuit ă prezentată de ține avantaje considerabile datorate faptului ca are la
bază tehnologia Java Remote Method Invocation. Pentru a eviden ția aceste avantaje trebuie s ă
facem câteva precizări despre limbajul Java. „Java este un limbaj de programare dezvoltat de
Sun Microsystems și reprezintă probabil unul din cele mai de succes limbaje din ultimile
decenii.Programatorii avansa ți îl prefer ă datorită faptului ca are o defini ție ordonat ăși bine
dezvoltată. Domeniul afa ceriilor îl prefera deoarece acesta domină o importantă noua
aplicație, programarea Web.” [HGi97] Chiar mai mult de atât, după cum putem citi și în
[VEN] Java reprezintă un limbaj orientat pe obiecte simplu, dinamic și distribuit. Acesta ofera
neutralitate față de arhitecturi, performan țe ridicate si capacitate multifir. Un mare avantaj al
acestui limbaj este soliditatea si securitatea, dar probabil cel mai mare avantaj îl constituie
portabilitatea acestuia . Un program Java rulează la fel pe orice sistem de operare care suportă
Java. Nu doar codul sursa este portabil, ci un program Java reprezinta un sir de octe ți care
poate fi rulat de interpretorul oricărui browser care oferă suport pentru Java. Astfel exista
posibilitatea rulării unui program Java pe aproa pe orice sistem. Platforma Java este bazată
doar pe software care rulează deasupra de alte platforme bazate pe hardware.
Avantaj ul cheie pe care îloferă Java Remote Method Invocation este simplitatea
implementarii, care duce la aplica ții mai flexibile, m ai robuste și mai mentenabile. Astfel se
pot implementa sisteme mai complexe cu relativa u șurinț ă. Totusi beneficiile nu se rezumă
doar la simplitate, ci la faptul ca prin RMI putem dezvolta un sistem distribuit, decuplând in
acela și timp obiectele client -server. Astfel se poate implementa un client care nu necesita
instalare cum este cazul și în aplicația prezentat ă, iar modificăriile aduse bazei de date duc
doar la recompilarea codului server -ului, în timp ce interfa ța server -ului și codul clientului
rămâ n nemodificate. Componentele aplica ției sunt ușor de di stribuit, aceasta permitând
dezvoltarea separată a fiecareia [Chr99].
Dezavantajele acestei tehnologii, cum este precizat și în [Chr99] sunt performanțele
mai slabe decât în cazul programării cu soclu ri TCP/IP cât și dificultatea de a implementa
server thread -safe. Din punct de vedere a performantei, stratul adi țional și faptul ca aplicația
trebuie să folosească registrul RMI, sunt cauza scăderii in eficien ță.În cazul în care se dore ște

Facultatea de Automatica si Calculatoare U.P.T.
5
implementarea server -ului în manieră concurentă este necesară implementarea unei structuri
bine pregătite.
Din punct de vedere al cerin țelor aplicației prezentate putem concluziona c ă
tehnologia Java Remote Method Invocation este ideala pentru implementarea jocului de Poker
în rețea, deoarece, in strâns ă legătura cu arhitectura de tip three -tier client -server, duce la
dezvoltarea unui sistem distribuit simplu, usor de utilizat de către clien ți, deoarece nu necesit ă
instalare, și cu avantajul c ă portabilitatea acestuia asigură faptul ca aproape oricare utilizator
Web va putea rula aplica ția pe calculatorul personal.
În capitolul 2 se regăsesc toate informa țiile necesare de Java Remote Method
Invocation. Pornind de la bazele tehnologiei, se va încerca o tr ecere în revist ă a avantajelor și
dezavantajelor folosirii metodei. Într -o privire de ansamblu asupra structurii RMI se va
discuta despre comunicarea RMI cu ajutorul suroga ților și a scheleților, cât și despre diferitele
nivele în care este structurată tehnologia. Din ac eastă privire de ansamblu nu lipsesc nici
descrierea server -uluiși a clientului aplicației , împreună cu comunicarea or cu serviciulde
nume RMI Registry. Tot în acest capitol se vor descrie clasele și metodele extinse, cât și
conceptele fundamentale de în cărcare dinamică a claselor, serializare, manageri și polițe de
securitate, colectarea de șeurilor și custom sockets. Capitolul 3 cuprinde specificațiile
aplicației, cu privire la funcționalitate cât și la interfața grafic ă a utilizatorului. Toate aceste
vor fi susținute de schemele și screenshot -urile necesare sublinierii lor. Capitolul 4
sumarizeaza moodul de proiectare a aplica ției pe parte de server, de clint cât și a interfețelor la
distanță. Capitolul 5 urmează să prezinte toate detaliile de implementa re relevante cu privire
la clasele care se regăsesc pe partea de server. Vor fi cuprinse aici clasele care stabilesc
comunicarea între client și server, cât și clasele care conțin logica jocului. În capitolul 6 se vor
contura implementările claselor de pe partea de client. Capitolul 7 este dedicat configurării și
rulării aplica ției. Aici vor fi enumerați pașii necesari pentru a putea instala și rula aplicația pe
un calculator nou. În final, lucrarea se încheie cu un capitol rezervat concluziilor asupra
aplicației prezentate.

Facultatea de Automatica si Calculatoare U.P.T.
6
Capitolul 2. Fundamente teoretice
2.1 Bazele Remote Method Invocation
Aplicațiile distribuite necesit ă ca procese ,aflate la spa ții de adrese diferite sau chiar pe
calculatoare diferite, sa poată comunica intr e ele. Mecanismul de bază oferit de limbajul de
programare Java™ oferă sprijin pentru socluri, care sunt flexibile și sunt suficiente pentru
comunicare generală. Cu toate acestea, socluri necesită angajarea clientului și server -ului în
protocoale la nivel de aplica ție pentru codare și decodarea mesajelor interschimbate, iar
această proiectare este dificilă și predispus ă la erori. Pentru a se potrivi cu semantica invocării
obiectelor, sistemele distribuite pe obiecte necesită Remote Method Invocation sau RMI . În
astfel de sisteme, un obiect surogat (stub) local gestionează invocările făcute pe un obiect la
distanță. Sistemul de invocare la distan ță a metodelor platformei Java descrise sunt special
proiectate pentru a opera in mediul aplica țiilor Java. Sistemu l RMI î și asum ă mediul omogen
al mașinii virtuale Java (JVM) și obține astfel avantajele modelului obiect al platformei Java
când este posibil[Sun06] .
Obiectivele urmărite in suportul oferit de limbajul Java pentru aplica ții distribuite sunt :

Suport pen tru invocarea la distan ță asupra obiectelor din ma șini virtuale diferite
Suport pentru apeluri inverse de la servere la applet -uri
Integreaza modelul obiectelor distribuite in limbajul de programare Java intr -un mod
natural, men ținând majoritatea semantici lor legate de obiecte ale limbajului de
programare Java
Diferențierea clar ă a modelului obiect distribuit de modelul obiect local al platformei
Java
Faciliteze scriere, intr -un mod cât se poate de simplu, a aplica țiilor distribuite sigure
Conservă propriet atea de siguran ță de tip prevăzută de mediul de runtime al platformei
Java
Suport pentru diferite semantici de refer ință ale obiectelor la distan țăspre exemplu
referințe nonpersistente, referințe persistente și lazy activation.
Menține m ediul sigur al pl atformei Java prevăzut de manageri de securitate și de
încărcători de clase.
La baza tuturor acestor obiective stă o cerin ță generală ca modelul RMI să fie atât simplu(u șor
de folosit) cât și natural (s ă se integreze bine în limbaj) ”, conform [Sun06].
Putem defini „un obiect la distan ță ca fiind un obiect ale cărui metode pot f apelate
(invocate) dintr -o altă ma șină virtuală Java, poten țial situat ă pe alt calculator. Obiectele la
distanță sun texem plareale unor clase care implementează metodele unor int erfețe la distanț ă.
Numai asemenea metode pot fi apelate de clien ții unui obiect la distanț ă.Dacă implementarea
conține și alte metode decât cele din interfața la distanț ă, acele metode nu pot fi apelate de la
distanță. Un argument de apel sau o valoare r eturnată de un obiect la distan ță pot fi de orice
tip Java serializabil. Pentru ca un client să apeleze o metodă a unui obiect la distan ță, trebuie
să dețină o referire la acel obiect. RMI include un server de nume prin clasa java.rmi.Naming
la care server ele se înregistrează și de la care clienții obțin referiri, dac ăștiu numele sub care e
înregistrat serverul ” [Ioa01].
Aplicațiile distribuite bazate pe tehnologia Remote Method Invocation ofer ă astfel
posibilitatea ca un obiect, aflat într -o ma șină virtuală Java, să invoce la distan ță metode ale
unui obiect situat în altă ma șină virtuală Java, ca și când acesta s -ar afla in aceea și mașina
virtuală. Mecanismul RMI prevede comunicarea necesară pentru ca aplica ția server s ă creeze

Facultatea de Automatica si Calculatoare U.P.T.
7
și să publice obiecte la distanță pe care clientul să poată invoca la distan ță metode. Această
comunicare se bazează pe trei pa și esențiali:
1.Localizarea obiectelor la distan ță; referințele obiectelor la distanț ă se pot ob ține fie din
serviciul de nume RmiRegistry despre care vom vorbi mai in detaliu mai târziu în
acest capitol, sau prin returnarea sau transmiterea acestora ca și parametru în cadrul
unei metode Remote.
2.Comunicarea cu obiectele la distan ță; aceasta rămâne transparentă fa ță de
programatori datorită mecanismului RMI c are va transforma aceasă comunicare intr -o
simplă invocare a unei metode aparent locale.
3.Încărcarea dinamică a claselor; reprezintă o caracteristica centrală a mecanismului
Remote Method Invocation, prin care acesta ob ține capacitatea de a desc ărca clasa
unui obiect dacă aceasta nu este definită în propria ma șină virtuală. Astfel tipul și
comportamentul unui obiect poate fi transmis altei ma șini virtuale Java, extinzând
comportamentul aplica ției în mod dinamic. Aceast ă încărcare se face pe baza oricărui
protocol suportat de platforma Java (ex. HTTP, file, FTP, etc. ).
2.2 Avantajele și dezavantajele tehnologiei RMI
Tehnologia RMI con ține la baz ă mecanismul apelului unei proceduri la distan ță sau
Remote Procedure Call (RPC), dar datorită faptului că RMI e ste proiectat pentru aplica ții de
tipul Java -spre-Java și este parte a abord ării orientate pe obiecte, prezintă o serie de avantaje
față de apelul procedurilor la distan ță:
Orientarea pe obiecte a tehnologiei RMI face posibilă transmiterea obiectelor Java atăt
ca parametru cât și ca valori returnate de invocarea unor metode la distanț ăși obiectele
nu trebuie astfel descompuse în tipuri primitve pentru a fi transmise.
Securitatea unei aplica ții RMI are la baz ă folosirea manageriilor de securitate care
previ n posibile atacuri din partea codului mali țios desc ărcat cât și din partea unor
applet -uri malițioase. Astfel aplicația r ămâne in siguran ță când utilizatorii descarcă
implementăriile necesare invocării unor metode la distan ță.
Simplitatea sistemul facilite ază scrierea unor aplica ții complexe într -un timp foarte
scurt. Clasele client și server conțin doar cateva linii de cod specifice mecanismului
RMI și astfel mentenan ța acestora devine foarte ușoar ă.
Comportamentul mobil al aplica țiilor RMI este datorat de scărcării dinamice a claselor
prin care comportamentul poate fi mutat dintr -o ma șină virtuală Java în alta fără prea
mari eforturi. Aplica ția devine astfel mult mai flexibil ă, iar schimbarea
comportamentului unei clase va produce schimbări doar in acea cla să pe partea de
server, nefiind necesară modificarea acesteia pe partea de client.
Tehnologia RMI facilitează programarea paralelă deoarece aceasta suportă
programarea multi -fir, necesară programării concurente a serverelor care vor deservi
mai mulți clienți în acela și timp.
Tansmiterea obiectelor facilitează folosirea tiparelor de programare orientată pe
obiecte. „Programarea orientată pe obiecte este o tehnică puternică care permite
refolosirea codului. Multe organiza ții folosesc programarea orientat ă pe obiecte pentru
a reduce din greutatea de a crea programe șipentru a cre ște flexibilitatea sistemelor
lor. RMI este orientat pe obiecte la toate nivelele -mesajele sunt trimise obiectelor la
distanțăși obiectele pot fi transmise și returnate. Toate patter n-uile de programare se
bazează pe polimorfismul obiectelor -abilitatea unui obiect de a avea mai multe
implementări. Partea generală a algoritmului nu trebuie să știe ce implementare este
prezentă, ci trebuie să știe doar ce trebuie s ă facă cu un astfel de obiect când prime ște

Facultatea de Automatica si Calculatoare U.P.T.
8
unul. Rmi transmite tipuri întregi, inclusiv implementarea, iar astfel putem folosi
programarea orientată pe obiecte -inclusiv pattern -uri de programare -oriunde in
soluțiile noastre distribuite, nu doar în computațiile locale. F ără sis temul pe deplin
orientat pe obiecte al RMI , trebuie sa abandonăm pattern -urile de programare –
împreună cu alte forme de refolosire a software -ului orientat pe obiecte. ”[Sun10]
Colectorul de de șeuri distribuit cur ăță sistemul de obiectele la distan ță spre c are nici
un client nu mai de ține nici o referinț ă. Acesta functionează similar colectorului de
deșeuri din interiorul mașinii virtuale. Vom evidenția utilitatea si necesitatea acestuia
în subcapitolele următoare.
Tehnologia RMI prezintă și o serie de dezav antaje referitoare la anumite dificulta ți de
dezvoltare și restricții :
Stratul adi țional reg ăsit deasupra soclurilor TCP/IP reduc performan țele
tehnologiei RMI fa ță de implementarea strict cu socluri
Limitarea tehnologiei la platforma Java. Acest impedime nt este rezolvat de
modelul distribuit CORBA (Common Object Request Broker) care oferă
neutralitate fa ță de limbajul de programare folosit. Astfel a fost dezvoltat
protocolul RMI -IIOP (Java Remote Method Invocation over the Internet Inter -Orb
Protocol) car e facilitează dezvoltarea unor aplica ții CORBA f ără a pierde
majoritatea avantajelor tehnologiei RMI.
Natura orientată pe legătură a aplica țiilor RMI duce la dezvoltarea unor sisteme
strâns cuplate în care scalabilitatea are mult de suferit.
2.3 Privire d e ansamblu asupra arhitecturii RMI
Sistemul RMI este proiectat pentru a oferi o bază directă și simpl ă pentru calculul
distribuit orientat pe obiect. Arhitectura este proiectată pentru a permite extinderea viitoare a
serverului și a tipurilor de referințe, astfel încât RMI să fie capabil să adauge func ționalitate
într-un mod coerent . Cand un server este exportat, tipul de referin ță este definit. Majoritatea
serverelor sunt exportate ca UnicastRemoteObject, care sunt server punct -la-punct
nereplicate. Referi nțele pentru aceste obiecte sunt adecvate pentru majoritatea tipurilor de
server, dar diferite tipuri de server pot folosi semantici de referin ță diferite. De exemplu, un
obiect MulticastRemoteObject ar avea semantica de referin ță necesară pentru a facilit a un
serviciu replicat. Referințele utilizate pentru serv ere UnicastRemoteObject comunică cu un
singur obiect se rver care rulează pe un host si port specific .Cu separarea Stub/referin ță, RMI
va fi capabil să adauge noi tipuri de referin țe.Oreferințănecesară serverel orreplicat ear
folosi multicast pentru înaintarea cereri lorde la server spre un set adecvat de replican ți, se
aduna răspunsuri le, și ar returna un rezultat corespunzătoare pe baza acestor răspunsuri
multiple. Un alt tip de referință ar put ea act ivaserver ulîn cazul în care nu a fost deja activ
într-o mașină virtuală. Clientul ar lucra transparent cu oricare dintre aceste tipuri de
referință .[Sun10]

Facultatea de Automatica si Calculatoare U.P.T.
9
Arhitectura Remote Method Invocation con ține trei nivele de baz ă:nivelul
stub/schel et; nivelul de referire la distan țăși nivelul transport. Nivelele și modul de
interconectare al acestor poate fi observate in figura 2 în care este prezentat întreg traseul între
client și server.
Fig. 2 Nivelele arhitecturii RMI
2.3.1 Suroga ți și sch eleți (Stubs and Skeletons)
Tehnologia RMI folose ște mecanismul standard pentru comunicarea cu obiecte la
distanță bazat pe suroga ți (stubs) și scheleți (skeleton) . Un stub se comportă ca un
reprezentant local sau proxy pentru un obiect la distan ță. Apel antul invocă o metodă pe stub –
ul local care este responsabilă pentru transmiterea apelului metodei spre obiectul la distan ță.
În RMI, un stub al unui obiect la distan ță implementează acela și set de interfețe la distanț ă ca
și obiectul în sine. Când este in vocată o metodă pe un stub local acesta ini țilizeaz ă o
conexiune cu ma șina virtual ă Java aflată la distan ță care con ține obiectul la distanț ă dorit. Se
serializează parametri și se transmit mașinii virtuale respective, iar apoi se așteapt ă rezultatul
metod ei invocate. În ultimul pas se deserializează valoarea rezultatului sau excep ția returnat ă
și se transmite înapoi apelantului. Stub -ul ascunde serializarea parametrilor cât și comunicarea
la nivel de re țea pentru a conserva mecanismul simplu de invocare al apelantului. În ma șina
virtuală Java aflată la distan ță, fiecărui obiect la distan ță îi corespunde un schelet. Acesta este
responsabil pentru transmiterea apelului spre implementarea obiectului la distan ță referit.
Când un schelet recep ționeaz ă o invocar e de metodă făcută de la distan ță începe să
deserializeze parametrilor metodei la distan țăși invoc ă respectiva metodă asupra
implementării obiectului la distan ță referit. În final, urmează serializarea v alorii rezultatului
sau excep țieispre apelant. În J ava 2 SDK, Standard Edition, v1.2 a fost introdus un protocol
adițional al stub -ului care elimină necesitatea pentru schele ți in mediile de dezvoltare bazate
doar pe platformele Java 2. În locul acestora se folose ște un cod generic care îndeplinește
sarcin iile schele ților din JDK 1.1. [Sun06]
Stub-urileși scheleții sunt generați automat de compilatorul RMI din compilarea
claselor serverului prin lini de comandă rmic.Această aplica ție este reg ăsită în versiunea Sun
al Java Development Kit. Invocarea cea mai simplă al rmic este de tipul:
„rmic [numele întreg al clasei inclusiv pachete]”

Facultatea de Automatica si Calculatoare U.P.T.
10
Presupunând că respectiva clasă se regăsse ște în classpath, aceasta genereaz ă două fi șiere de
tip class adi ționale în directorul clasei originale. Numele claselor generat e vor fi identice cu
numele clasei originale la care se adaugă sufixul _Skel și _Stub. Pentru a vedea codul surs ă al
celor duă clase noi trebuie să folosim flag -ul–keep al comenzii rmic. [Wil01]
2.3.2 Nivelul de referire la distan ță
Aceste nivele este responsabil pentru efectuarea unor protocoale specifice referirilor la
distanță independente de stub -uriși de scheleți. Astfel definește semanticile necesare invocarii
unei metode la distan ță a conexiunii RMI. Protocoalele de invocare efectuate de acest n ivel
sunt:
Invocare unicast point -to-point
Invocare asupra grupurilor de obiecte replicate
Suport pentru referiri persistente ale obiectelor la distan ță
Strategiile de replicare și de reconectare
Transmisia datelor spre nivelul de transport se face prin ab stractizarea unei conexiuni
orientate pe flux (stream). [Ven]
Nivelul referirii la distan ță conține un obiect RemoteRef care reprezintă legătura spre
obiectul care implementează serviciul la distan ță. Obiectul stub utilizează metoda invoke() a
obiectului RemoteRef pentru a transmite mai departe apelul metodei. Obiectul RemoteRef
întelege semanticile de invocare pentru servicii la distan ță. Implemetarea RMI din JDK 1.1
pune la dispozi ție doar o singur ă cale pentru conectarea clienților la serviciile la dist anță: o
conexiune unicast point -to-point. Înainte ca un client să poată folosi un serviciu la distan ță,
acest serviciu trebuie instan țiat pe server și trebuie exportat sistemului RMI, iar in cazul în
care reprezintă serviciul primar trebuie și înregistrat în registrul RMI. Implementarea din Java
2 SDK al sistemului RMI sunt adăugate noi semantici pentru conexiune client -server. În
această versiune, RMI oferă suport pentru obiecte la distan ță activabile. Când un apel al unei
metode ajunge la proxy -ul unui ob iect activabil, RMI determină daca implementarea
serviciului la distan ță este un obiect inactiv. Daca este inactiv, RMI va instan ția obiectul și îi
va restaura starea dintr -un fi șier de pe disc. Odat ă ce un obiect activabil este în memorie,
acesta se compo rtă ca un obiect la distan ță normal din JDK 1.1. Sunt posibile și alte semantici
de conexiune, cum ar fi multicast, în care un proxy poate sa trimită un apel spre mai multe
implementări simultan și să accepte primul răspuns. Astfel se îmbunătă țește timpul de răspuns
și disponibilitatea. În viitor, Sun ar putea să mai adauge și alte semantici de invocare la
RMI.[Ora10]
2.3.3 Nivelul transport
„Nivelul transport este responsabil pentru:
Stabilirea unor conexiuni cu spa țiile de adrese la distanțăși gestionarea lor
Așteptarea unor apeluri și stabilirea leg ăturilor pentru apelurile sosite
Gestonarea unei tabele de obiecte la distan țăîn spațiul curent de adrese
Localizarea dispecerului pentru un apel la distanțăși transmiterea conexiunii c ătre
acesta
Există 4 abstrac ții fundamentale la nivelul transport:
Unpunct fnal (endpoint) care reprezintă abstrac ția folosit ă pentru a denota un
spațiu de adrese sau o mașina virtual ă Java. În implementare, un punct final poate
fi corelat cu transportul propriu. Astfe l dacă avem un punct final putem ob ține
instanță de transport anume

Facultatea de Automatica si Calculatoare U.P.T.
11
Uncanal esteabstracția pentru leg ătura între două spa ții de adrese. Aceasta este
responsabilă pentru gestiunea conexiunilor între spațiului local șispațiul de adrese
la distanță pentru care acesta reprezintă canalul de comunicare.
Conexiunea este abstracția pentru gestionarea canalelor; acceptă apeluri pe
conexiunile de intrare și dispecerizeaz ăspre nivelurile superioare
Transport este abstrac ția care gestioneaz ă canalele de comunic are. Într -un
transport există doar un canal pentru fiecare pereche de spa ții de adrese. Fiind dat
un punct final pentru un spa țiu de adres ă la distan ță, un transport pregăte ște un
canal spre acel spa țiu. Abstracția transportului este responsabil ă pentru ac ceptarea
apelurilor și a conexiunilor spre spațiul de adrese, preg ătind un obiect de tip
conexiune pentru apel și dispecerizând spre nivelele mai înalte în flux. ” [Ven]
Pot exista mai multe transporturi pentru un spațiu de adrese, adic ă s-ar putea lucra și cu
TCP și cu UDP .Reprezentarea concretă a unei referiri la distanță constă dintr -un punct fnal și
unidentfcator de obiect și se numește referire vie (live reference) . Transportul folose ște
punctul fnal pentru conexiunea cu spa țiulobiectului, iar acol o ident ificatorul selectează
obiectul [Ioa01].
Fig.3 Folosirea liberă a conexiunilor de tip TCP/IP intre ma șini virtuale JAVA
Peste protocolul TCP/IP, RMI folose ște un protocol la nivel de cablu numit Java Remote
Method Protocol (JRMP). Acesta este un p rotocol bazat pe flux disponobil în două versiuni .
Prima versiune a fost lansată odată cu versiune de RMI din JDK 1.1 și aceasta folosea
Scheleți pentru clasele server. A doua versiune a fost lansat ă împreună cu Java 2 SDK și a
fost optimizată pentru perfo rmanță, nefiind necesai Schele ții. [Ora10]
2.3.4 Clientul
Clientul poate fi dezvoltat ca o aplica ție stand -alone care se execută independent fa ță
de un browser sau poate fi un Applet Java care nu se execută în mod stand -alone ci aderă la
un set de conve nții prin intermediul c ărora pot rula în orice browser care oferă suport pentru
Java. Responsabilită țiile clientului sunt de a căuta în RMIRegistry obiectul la distan țăși de a
obține apoi o referinț ă către acesta. După ce ob ține referința poate invoca me todele la distan ță
ale obiectului la distan țăși poate transmite argumentele necesare cu tipuri de date primitive
sau obiecte serializabile. Clientul va apela metodele la distan ță ca și când obiectul server s -ar
regăsi în propria ma șină virtuală, mecanismu l de cumunicare rămânând transparent. Codul
clientului trebuie să importe pachetele java.rmi și java.rmi.RMISecurityManager.
Înregistrarea unui security manager este obligatorie, deoarece constituie „sandbox” -ul ce
înconjoară programul, iar în lipsa acestu ia se pot încărca dinamic doar clase din sistemul de
fișiere local.

Facultatea de Automatica si Calculatoare U.P.T.
12
2.3.5 Server -ul RMI
Server -ultrebuie , exact ca și în cazul clientului, s ă instaleze un manager de securitate
pentru a preveni ac țiunile malițioase. Odat ă ce server -ul a instalat man agerul de securitate,
trebuie să creeze o instan ță a obiectului la distan ță pe care dore ște să îl exporte. Registrul RMI
trebuie să ruleze pe aceea și mașin ă cași serverul, iar obiectele la distanț ă pot fi atunci
înregistrate pentru a le face accesibile clienților. Server -ul trebuie sa înregistreze obiectul la
distanță cu acela și nume cu care acesta va fi c ăutat de client. Doar serviciile disponibile în
interfețele la distanț ă vor putea fi invocate de către clien ți.Acesta are și responsabilitatea de a
recepționa invoc ările metodelor la distan ță de la schelet, primind și parametri dupa scoaterea
din flux. Tot server -ul este responsabil și de transmiterea c ătre schelet al rezultatului sau a
excepției metodei apelate.
2.3.6 Registrul RMI
Tehnologia Remote M ethod Invocation con ține un serviciu de c ăutare de nume numit
Registrul RMI .Pentru început putem defini serviciul de nume ca fiind o resursă centralizată,
folosită de un număr de aplica ții ca o resurs ă de tipul „agendă telefonică”. Mai exact,
reprezintă o aplicație ușor de localizat și bine cunoscut ă, care con ține nume logice ale
obiectelor la distan ță, astfel încât programele client să poată u șor localiza și folosi aplicațiile
server căutate. Prin „nume logice” în țelegem string -uri, iar prin găsirea unui nume întelegem
returnarea unei referin țe pe baza unei egalit ăți case -sensitive între numele căutat și numele din
registru. Registrul returnează un stub care incapsulează informa ție despre mașina pe care
rulează registrul cât și portul pe care aceasta ascul tă. Stubul ascunde aceste informa ții
clientului și pur și simplu expune metodele care pot fi invocate pe obiectul server. Un serviciu
de nume poate întalni trei scenarii diferite în functie de cum îi este făcut clientului cunoscută
locația serverului:
Clientul știe deja unde s ă găsească serverul. Loca ția serverului poate fi hardcodat ă în
aplicația clientului sau locația acestuia este stocat ă într -o resursă secundară (un fi șier
text,etc.)
Utilizatorul transmite aplica ție client locația serverului, iar acesta stochează loca ția
serverului pentru accesări ulterioare.
Un server standard regăsit într -o locație bine cunoscut ă servește ca punct de indirecție.
Astfel, clientul interoghează serviciu de re țea pentru a afla poziția serverului. Aceasta
este soluțiaservi cilor de nume, unde clientul știe unde se afl ă serviciu și urmeaz ă să
afle cum se poate conecta la aplica ția server.
Folosirea reistrului RMI implică includerea pachetului java.rmi.Naming care define ște
metodele următoare necesare:
public static void bind( String name, Remote obj)
public static void rebind(String name, Remote obj)
public static void unbind(String name)
public static String[] list(String name)
public static Remote lookup(String name)
Aceste metode se împart în două seturi :cele necesare codul ui de lansare al clientului și cele
necesare codului de lansare al serverului. Primele trei metode sunt folosite de codul de lansare
al serverului pentru a înregistra și a scoate din registrul RMI obiectele la distanț ă.

Facultatea de Automatica si Calculatoare U.P.T.
13
Registrul RMI este o solu ție fiabi lă care rezolvă problema bootstr apping -ului a
aplicațiilor distribuite, iar avantajele principale ale acesteia sunt ușurințta de administrare,
ușurința cu care este g ăsitși folosit de clienți, cât și viteza de execuție a sa. Din punct de
vedere a securită ții, pentru a nu fi vulnerabil fa ță de posibile atacuri, orice apel care
înregistrează un obiect în registru trebuie să origineze dintr -un proces care rulează pe aceea și
mașină cași registrul în sine. Astfel, nu se previn invoc ăriile ilicite, dar se previ nalterările de
structură si atacuri asupra aplica ție. [Wil01]
2.4 Interfe țele, clasele și metodele la distanț ă
Interfețele și clasele responsabile pentru comportamentul specific unei sistem Remote
Method Invocation sunt definite în ierarhia pachetului java.rmi . În figura 4 putem urmări
relațiile dintre aceste interfețe și clase. [Sun06]
Fig. 4 Rela țiile claselor și interfețelor principale ale sistemului RMI [Sun06]
2.4.1 Interfa ța java.rmi.Remote
În RMI, o interfa ță la distan ță este o interfa ță car e declară un set de metode care pot fi
invocate dintr -o ma șină virtuală la distan ță. O interfa ță la distan ță trebuie să satisfacă
urmatoarele condi ții:
Interfața trebuie s ă extindă, direct sau indirect, interfa țajava.rmi.Remote
Declararea metodelor treb uie să includă excep țiajava.rmi.RemoteException (sau o
superclasă a acesteia cum ar fi java.io.IOException saujava.lang.Exception )
O interfa ță la distan ță poate să extindă o altă interfa ță, cat timp toate metodele
interfeței extinse satisfac cerințele de declarație a unei metode la distanț ă.[Sun06]
2.4.2 Clasa RemoteException
Clasa java.rmi.RemoteException este superclasa excep țiilor aruncate de mecanismul
RMI în timpul unei invocări la distan ță. Pentru a asigura robuste țea aplicațiilor folosind
sistem ul RMI, fiecare metodă la distan ță declarată într -o interfață la distan ță trebuie să
specifice in clauza sa throws o excep ție de tipul java.rmi.RemoteException sau o superclasă a
acesteia. Această excep ție este aruncat ă când o metodă la distan ță nu reu șește dintr -un motiv.
Unele motive care duc la astfel de nereu șite includ:
Eșecul comunic ării (serverul este de negăsit sau refuză conexiuni)

Facultatea de Automatica si Calculatoare U.P.T.
14
Eșec al punerii sau soaterii din flux al unui parametru sau a rezultatului unei metode la
distanță
Erori de protocol
Clasa RemoteException este o excep ție verificat ă, nu o excep ție de Runtime [Sun06]
2.4.3 Clasa RemoteObject și subclasele ei
Funcțiile serverului RMI sunt prev ăzute de java.rmi.server.RemoteObject și de
subclasele java.rmi.server.RemoteServer , java.rmi.s erver.UnicastRemoteObject și
java.rmi.activation.Activatable . Această clasă oferă implementare pentru clasa
java.lang.Object , mai exact imlementare a metodelor hashCode, equals și toString care sunt
sensibile pentru obiectele la distan ță. Metodele necesar e creări și export ării unui obiect la
distanță sunt prevăzute de clasele UnicastRemoteObject și Activatable. Subclasa identific ă
semantica referin ței la distanț ă, cum ar fi starea obiectului la distan ță ca fiind simplă sau
activabilă. Clasa UnicastRemoteOj ect define ște un obiect la distan țăsingleton (unicast) al
cărui referin ță este validă doar cât timp procesul serverului este viu. Clasa Activatable este o
clasă abstractă care define ște un obiect la distanț ă activabil care î și pornește execuția doar
când metodele sale la distan ță au fost invocate și poate s ă se dezactiveze când este
necesar.[Sun06]
2.5 Încărcarea dinamică a claselor
Rmi permite parametrilor, valorilor returnate și excpțiilor transmise în apeluri RMI s ă
fie orice obiect serializabil. RMI folose ște serializarea obiectelor pentru a transmite date dintr –
o ma șină virtuală în alta și anoteaz ă fluxul apelului informa ția locației specifice, astfel încât
definiția clasei s ă poată fi încărcată de către receptor. Când parametri și valoril returnate ale
unei inocări a unei metode la distan ță sunt scoase din flux în scopul de a deveni obiecte
normale în ma șina virtual ă Java receptoare, defini ția claselor este necesar ă pentru toate
tipurile de obiecte scoase din flux. Procesul de scoatere din flux înce arcă prima dată să
găsească defini țiile necesare în classpath -ul local. RMI prevede și facilitatea de înc ărcare
dinamică a defini țiilor claselor pentru tipurile de obiecte transmise ca parametru și ca valori
returnate ale invocărilor metodelor la distan țădin locații de rețea specificate de punctul final
transmițător. Aceasta include și desc ărcarea dinamică a stuburilor corespunzătoare unei
implementări a unui obiect la distan ță anume, cât și a oric ărui tip transmis prin valoare în
apelurile RMI, cum ar fi subclase a unui tip de parametru declarat care nu este accesibil pe
partea de recep ție. Pentru a sprijni înc ărcarea dinamică, runtime -ul RMI folose ște subclase
speciale ale java.io.ObjectOutputStream șijava.io.ObjectInputStream pentru scoaterea și
introdu cerea în flux a parametrilor sau a valorilor returnate. Aceste subclase suprascriu
metoda annotateClass a clasei ObjectOutputStream șiresolveClass a clasei
ObjectInputStream pentru a comunica informa ții despre locația fișierelor class ce conțin
definițiile necesare. Pentru fiecare descriptor de clase scris unui flux RMI , metoda
annotateClass adaugă rezultatul metodei java.rmi.server.RMIClassLoader.getClassAnnotation
, care poate fi și null sau poate fi un obiect String reprezentând URL -ul codebase -ului din care
punctul final la distan ță ar trebui sa descarce defini țiile claselor necesare. Identic și în cazul
citirii din fluxul RMI se vor folosi metoda resolveClass care returnează rezultatul apelului la
RMIClassLoader .[Sun06]

Facultatea de Automatica si Calculatoare U.P.T.
15
2.6 Serializarea
Serializ area e ste un proces de convertire a unui set de referin țe a unor obiecte, care
conțin referințe intre ele într-un flux de bytes, care poate fi trimis printr -un soclu, poate fi
salvat ca fi șier sau poate fi manipulat ca flux de date. Serializarea reprezint ămecanismul
folosit de Remote Method Invocation pentru transmiterea obiectelor între ma șinile virtuale
Java, fie ca parametri a unor metode invocate de un client pe un obiect la distan ță, fie ca
valoare returnată a unei astfel de metode. Serializarea este un mecanism con ținut de miezul
librăriilor Java pentru scrierea unui graf de obiecte într -un flux de date. Acest flux de date
poate fi manipulat programatic sau se pot crea „copi adânci” ale obiectelor prin inversarea
procesului. Această inversare este num ită deserializare. Serializarea are trei scopuri
fundamentale în func ție de fluxul folosit:
Dacă fluxul folosit este FileOutputStram , atunci datele vor fi automat copiate într -un
fișier, av ănd rolul de mecanism de persisten ță.
Dacă fluxul folosit este Byte ArrayOutputStream, atunci datele vor fi copiate într -un
tablou de byte -uri. Acest tablou de byte -uri poate fi folosit pentru a crea copi ale
obiectelor originale, asemenea unui mecanism de copiere.
Dacă fluxul folosit vine de la un soclu, atunci datele vor fi automat transmise soclului
receptor, de unde cealaltă aplica ție va hot ărâ ce se va întâmpla.
Este important să men ționăm că serializarea este independentă de algoritmul folosit. Dacă
avem o clasă serializabilă, putem transmite sau face copi doar prin schimbarea fluxului de
ieșire.[Wil01 ]
O parte importantă a serializării implică metadatelor claselor asociate cu o instan ță
anume. Majoritatea instan țelor reprezint ă mai mult de o clasă. Spre exemplu, o instan ță String
reprezintă și o instanț ă Object. Totu și, orice instan ță, reprezintă un numar mic de clase, iar
acestea pot fi scrise ca o secven ță: C1,C2,C3…Cn în care C1 este o superclasă a lui C2, C2
este o superclasă a lui C3, si a șa mai departe. Aceast ă secvență este lineară, deorece Java este
un limba j ce suportă o singură extindere. [Wil01]
Fig.4 Diagramă de mostenire [Wil01]
După ce sunt scoase informa țiile asociate clasei, mecanismul de serializare stocheaz ă un
descriere a celei mai derivate clase, datele asociate cu instan ța, interpre tată ca o instan ță a
celei mai de sus superclase C1, și datele asociate instanței, interpretat ă ca o instan ță a clasei

Facultatea de Automatica si Calculatoare U.P.T.
16
C2. Procesul continuă pănă când se ajunge la datele asociate instan ței celei mai derivate clase.
Tipul instan ței este astfel stocat și to ate stările serializabile sunt por ționate in buc ăți discrete
care corespund structurii clasei. Prin descriere a celei mai derivate clase întelegem :
ID-ul de versiune al clasei, care este un întreg folost pentru validare fi șierului .class
O variabilă boole ană care confirmă/infirmă dacă au fost implementate metodele
writeObject/readObject
Numărul de câmpuri serializabile
O descriere a fiecărui câmp (con ținând numele și tipul acestuia)
Date suplimentare rezultate de metoda annotateClass() a clasei ObjectOutpu tStream
O descriere a superclasei în cazul în care aceasta este serializabilă
Mecanismul de serializare converte ște automat, runtime, metadatele unui obiect astfel încât
orice instan ță poate fi serializată de programator cu un efort minim.[Wil01]
Mecanism ul Remote Method Invocation nu folose ște, defapt, clasele
ObjectOutputStream și ObjectInputStream, ci folosește propriile clase pentru a fi capabil sa
suprascrie câteva metode protejate. Acelea și modific ări sunt facute de către RMI și la
algoritmul de dese rializare. Cele mai importante clase suprascrise de sistemul RMI sunt:
protected void annotateClass(Class cl)
protected boolean enableReplaceObject(boolean enable)
protected Object replaceObject(Object obj)
Din punct de vedere al versiunilor claselor, a par probleme doar în momentul în care o clasă se
modifică. Prin modificare, metainforma țiile create vor deveni învechite și nu vor mai
corespunde cu implementăriile curente. Aceste modificări pot fi de două tipuri: modificări in
clasa curentă sau modificăr i în ierarhia de mo ștenire. Primul tip nu poate fi cu adevărat
remediat, ci doar prin încercări de a adapta codul nou la cel vechi. Al doilea tip de modificare,
cel al clasei curente, poate fi rezolvat local din defini ția clasei. Pentru ca mecanismul de
serializare să detecteze când o astfel de problemă de versiune apare, el trebuie să fie capabil să
detecteze situa țiile în care o clas ă a fost modificată. Ca și in toate celelalte aspecte ale
serializării, există o metodă de bază prin care se poate rezolva a ceastă problemă, iar această
metodă poate fi suprascrisă după necesitatea fiecărei aplica ții.Mecanismul de serializare
rezolvă această problemă prin implicarea metodei hashCode, creând un hashcode care con ține
informații despre numele clasei, interfețele implementate, descrierea tuturor metodelor,
câmpurilor și a constructorilor care nu sunt declarați private. Acest hashcode este numit
identificatorul unic al fluxului clasei și este foarte sensibil la schimb ări. Comportamentul de
bază al mecanismului de se rializare este de a înregistra modificăriile chiar dacă acestea nu
aduc schimbări semnificative comportamentului clasei. Astfel, în cazul unei schimbări ,
mecanismul de serializare refuză să creeze o instan ță a unei clase noi, folosind datele
serializate a unei clase vechi. [Wil01]
Serializarea reprezintă un mecanism generic de introducere și scoatere din fluxul de
date ce prezintă multe op țiuni pentru schimbarea comportamentului în funcție de necesit ăți.
Toate algoritmele generice sunt, de obicei, mai lente , iar mecanismul de serializare nu face o
excepți a acestei reguli. Serializarea este uneori lent ăși consumatoare din punct de vedere al
lățimii de band ă folosite. Pentru a îmbunătă ți performanțele mecanismului de serializare
putem începe prin setare seri alVersionUID -ului, care este adesea o îmbunătă țire
considerabilă, datorată faptului că mecanismul nu mai trebuie să parcurgă toate câmpurile și
apoi să genereze hashcode -ul necesar, ci doar caută valoarea existentă a acesteia. O altă
problemă de performan ță o reprezintă formatul prolix al datelor cât și transmiterea mai multor
date decât este necesar aplica ției. Chiar dac ă la fiecare transmitere se trimit doar câteva zeci
de bytes de date redundante, în ansamblu, aceasta poate duce la scaderi de performan ță
sesizabile, iar optimizarea transmiterilor devine un obiectiv foarte important. [Wil01]

Facultatea de Automatica si Calculatoare U.P.T.
17
2.7 Manageri și polițe de securitate
Platforma Java 2 con ține un model de securitate diferite faț ă de platforma anterioară.
Comportamentul acestui model implică fapt ul că o bucată de cod nu poate accesa nimic în
afara ma șinii virtuale Java propri, decât în cazul în care îi sunt acordate permisiile necesare.
Asta implică faptul că o aplica ție de tip „legacy” ,căreia nu îii sunt acordate permisiile
necesare, nu va mai f i capabilă să deschidă conexiuni prin socluri.
Într-o aplicație distribuit ă pot apărea diferite probleme de securitate:
Confidențialitatea datelor
Integritatea datelor
Autorizare și validare
Când vine vorba de applet -uri, problema securită ții se rezolv ăprin restric ționarea accesului
acestuia la hard disc, astfel applet -ul nu poate colec ționa informații și nici nu poate șterge
fișiere . Accesul appletului este restric ționat astfel la pagina Web în care a fost desc ărcat și are
acces doar la informa țiile pe care le prime ște de la server și la informațiile pe care acesta la
primi ște de la utilizator. Aceast ă metodă se nume ște „punerea applet -ului într -un sandbox”
[Wil01].
2.7.1 Permisiuni
Java 2 introduce o listă de permisiuni care trebuie acordate fiecărei bucăți de cod . În
mod normal, orice aplica ție deține de la început cel mai restrictiv set de permisiuni. Acest set
restrictiv se poate modifica prin acordarea permisiilor necesare efectuării anumitor ac țiuni,
cum ar fi deschiderea unei conexiuni de tip so clu pe un port anume. Toate aceste permisiuni
se regăsesc, în mod normal, într -un fi șier numit security policy . Aceste poli țe se pot crea în
două moduri și anume:
Programatorii le crează pentru a lista permisiile necesare aplica ției lor pentru a
funcționa corect. Această poli ță este apoi livrată împreună cu aplica ția client.
Utilizatorii pot crea propriile poli țe de securitate sau pot modifica polițele livrate
împreună cu aplica ția client.
În Java 2 există nouă tipuri de bază de permisiuni:
Permisiuni AWT
Permisiuni de fi șier
Permisiuni de re țea
Permisiuni de soclu
Permisiuni privind anumite proprietă țiile aplicației
Permisiuni de reflec ție
Permisiuni privind runtime -ul
Permisiuni de securitate
Permisiuni de serializare
Fiecare din aceste tipuri de permisiun i define ște un mod specific în prin care „sandbox” -ul
poate fi încălcat. Pentru aplica țiile tipice RMI cele mai importante tipuri de permisie sunt cele
de tip AWT, fi șier, soclu și cele privind propriet ățiile aplicației. Permisiuniile AWT
reprezintă permis iunea care controlează accesul la resurse asociate ecranului și are rolul de a
preveni ac țiuni malițioase cum ar fi afișarea unor buc ăți de cod menite s ă păcălească
utilizatorul în introducerea unor date confiden țiale, sau interogarea clipboard -ului pentru a
obține informații importante.[Wil01]

Facultatea de Automatica si Calculatoare U.P.T.
18
Permisiile de fi șier constrâng abilitatea unei aplicații de a efectua operații pe fișiere
(citire, scriere, executare și ștergere) și trebuie acordate cu mare atenție. Permisiile privind
soclurile reprezintă constr ângerile efectuate asupra opera țiilor pe socluri:
Resolving an address
Connecting
Listening for connections
Accepting a connection
Acestor opera ții pe socluri le sunt asociate permisiuniile resolve, accept, listen și connect. Ele
necesită specificarea unor adrese IP acceptate cât și a unei plaje de porturi. Ultimul tip
menționat este cel privind permisiile propriet ățiilor. Clasa System define ște în pachetul
java.lang o referință statică spre un obiect singleton care poate fi ob ținut prin apelul
System.getPr operties() . Acest obiect reprezintă o instan țăajava.util.Properties și conține un
set canonic de perechi nume -valoare care specifică informa ții despre mașina virtual ă Java, cât
și toate proprietă țiile setate în linia de comand ă prin flag -ul-D. [Wil01]
2.7.2 Manageri de securitate
În ma șina virtual ă Java permisiuniile sunt întrebuin țate de o instanț ă a clasei
SecurityManager . Când un program încearcă să interprindă o ac țiune care necesit ă
perrmisiuni, instan ța SecurityManager este interogat ă pentru a vedea dacă programul de ține
permisiuniile necesare. O singură instan ță a unui SecurityManager poate fi instalată într -o
mașină virtuală Java și aceasta nu poate fi schimbat ă. Cea mai simplă modalitate de a instala
un manager de securitate este de a seta pr oprietatea sistem la lansarea JVM:
java –Djava.security.manager application
Aceasta va crea o instan țăa managerului de securitate și o va instala la execuția mașinii
virtuale înainte de executarea codului specific aplica ției. Folosind proprietă țiile
sistemuluipentru a instala un manager de securitate este deobicei foarte convenabil. În
sistemele RMI însă, managerul de securitate se instalează, în mod normal, apelând metoda
System.setSecurityManager() cu argumentul new RMISecurityManager() . Motivul aceste i
instalări este că încărcarea dinamică a claselor nu va func ționa decât dac ă există deja un
manager de securitate instalat. RMI prevede un manager de securitate simplu numit
RMISecurityManager din pachetul java.rmi . Acesta, pur și simplu, subclaseaz ă mana gerul de
securitate standard fără a adăuga func ționalitate. Motivul folosirii managerului de securitate
RMI este faptul că acesta scoate în eviden ță motivul instalării sale cât și faptul c ă acesta are
capacitatea de a evolua odată cu aplica ția.[Wil01]
Managerul de securitate intră în ac țiune când este apelat ă o metodă ce necesită
anumite permisiuni. Ca parte a implementării acelei metode se face un apel la managerul de
securitate care returnează o excep ție în cazul viol ării unei permisiuni sau se întoarce silențios
din apelul său, permi țând metodei s ă continue. [Wil01]
2.7.3 Poli țe de securitate
În mod normal, două sau trei poli țe de securitate sunt folosite la rularea unei aplicații:
Polița global ă; reprezintă o poli ță care se aplică tuturor aplica țiilorși tuturor
utilizatorilor. În mod obi șnuit reprezint ă polița de securitate livrat ă cu JRE -ul existent
sau o poli ță definită de administrator. Aceasta se regăse ște în
${java.home}/jre/lib/security/java.policy. On my machine, this resolves to c: \program
files\jdk1.3 \jre\lib\security \java.policy.

Facultatea de Automatica si Calculatoare U.P.T.
19
Polița specific ă utilizatorului; reprezintă o poli ță folosită pentru rularea aplica țiilor de
un utilizator anume
Polița specific ă aplicației; poliț ă care este livrată cu aplica ția, definind permisiuniile
necesare rulării corecte a aplica ției. Aceasta nu are o locație specific ă, dar locația ei
trebuie precizată în parametri sistemului la rulare.
În concluzie, dacă unul dintre aceste fi șiere arat ă că o opera ție este permis ă, atunci acea
operație va fi permis ă, chiar dacă celelalte fi șiere nu precizeaz ă acest lucru. O poli ță de
securitate constă din mai multe declara țiigrant . Fiecare declara ție are urm ătorul format:
grant [nume] [codeBase URL] {
// listă de permisii
};
În traducere înseamnă: clasa încărcată din codebase -ul de la URL cu numele respectiv are
următoarele permisii. [Wil01]
Un exemplu de poli ță de securitate ca acordă toate permisiile este:
grant {
permission java.security.AllPermission;
} ;
Acest tip de poli ță care acord ă toate permisiunile trebuie folosit doar în stadiu de
dezvoltare pentru rularea și testarea aplicației. În cazul unei aplicații finite, o poliț ă de
securitate bine definită poate proteja si asigura buna desfă șurare a sistemului.
2.8Custom Socket s
În mo d implicit, RMI folose ște clasele socket standard definite în pachetul java.net
pentru a trimite informații prin re țea.Serverele utilizează instanțe ale clasei ServerSocket
pentru a asculta pentru conexiuni, si cliențiiinițializează conexiuni folosind in stanțe ale clasei
Socket. Aceste socluri trimit informații ca text simplu, fără nici o criptare sau compresie. Pe
latura pozitivă, aceasta implică o utilizare redusă a CPU (informația nu este transformată în
nici un fel) și sunt cel mai simplu de utilizat. Aceasta din urmă este adevărat, deoarece
compresia este destul de dificil de realizat. Semantica flush (), în special cu
GZIPOutputStream, nu sunt în întregime compatibile cu ideea de a transmite invocații ale
metodelor de la distanță ca unită ți auto -conținute .Pe partea negativă a conceptului, aceste
socluri folosesc mai mult de lățime de bandă decât este necesar, și informațiile sunt foarte
vulnerabile în timpul în care acestea sunt trimise prin rețea. Astfel avem două motive cheie
pentru utilizarea socl urilor personalizate:
Dacă sistemul nu se află într -o rețea securizat ă, iar informa țiile transmise prin rețea
sunt sensibile este indicată folosirea unor socket -uri de criptare, cum ar fi socket -urile
SSL.
Dacă aplica ția se afl ă într -o rețea foarte conges tionată, unde lă țimea de band ă
reprezintă o problemă, este indicată compresia informa ției înainte de transmiterea prin
rețea.
Înambele cazuri, se face un compromis: resursele unei singure ma șini, cum ar fi timpii
procesorului, sunt folosite pentru a trans forma datele pentru mai bune caracteristici de rețea.
În plus față de aceste compromisuri, există local (de exemplu, care nu implică cum datele sunt
trimise prin rețea), motive pentru a utiliza un socket custom. Unu motiv comun este de a
monitoriza utiliza rea socket -urilor și de a urmări cât de multă informație este trimis ă prin
rețea.Acest motiv de performan ță duce la utilizarea socket -urilor cu compresie. [Wil01]

Facultatea de Automatica si Calculatoare U.P.T.
20
2.9 Colectarea de șeurilor
Suportul de execu ție RMI folosește fire de execuție pentru realiz area apelurilor la
distanță: apelurile din ma șini virtuale client diferite se execut ă în fire diferite, iar apelurile
distincte din aceea și JVM pot fi executate doar în fire de execuție diferite datorit ă politcii de
reutlizare a socketurilor. Pentru colect area automată a de șeurilor în formă distribuită a fost
implementat un algoritm bazat pe numărarea referin țelor în mașina virtual ă a clientului. Când
apare o referire vie se incrementează contorul de referiri al acestei ma șini virtuale. La prima
astfel de r eferire la obiect se transmite serverului un mesaj de tip ”referenced”. Dacă se
constată local că o referire vie nu mai este folosită se decrementează contorul de referiri. Dacă
contorul a ajuns la zero, se transmite un mesaj de tip ”unreferenced” către se rver. Dacă în
mașina virtual ă a serverului, un obiect nu mai are referiri ale clien ților, se spune c ă acesta are
o ”referire slabă” și poate fi colectat când nu mai are referiri locale. Dac ă un obiect are referiri
locale, el poate fi transmis în apeluri la distanță sau poate fi returnat clien ților. Astfel,
obiectele la distan ță se colectează doar când nu mai au nici un fel de referiri. [Ioa01]
2.10 Componente grafice în Java
Pachetele fundamentale, în platforma Java, pentru realizarea interfe țelor grafice sunt
java.awt și java.swing. Primul pachet, java.awt, a ap ărut incă de la versiunea 1.1 a platformei
și se caracterizează prin faptul că, clasele sale folosesc direct facilită țile grafce ale sistemului
de operare pe care rulează, astfel că, în consecin ță,aspectul interfe ței grafice depinde de
sistemul de operare sub care rulează aplica ția. În java.swing a fost realizat ă independen ța de
platformă, adică aspectul interfe ței va fi același indiferent de suportul din sistemul de operare.
Clasele pachetului jav a.swing mo ștenesc îns ă facilitațile utile ale claselor corespunz ătoare din
pachetul java.awt. Convenional se vorbe ște despre interfețe grafice AWT sau interfețe grafice
Swing, după pachetul utilizat la realizare. [Jur06]
De la apari ția limbajului Java, ac este biblioteci, au trecut prin cele mai multe
schimbări în trecerile de la o versiune la alta. Un prim factor al acestor modificări a fost
portabilitatea, destul de dificil de realizat. Integrarea mecanismelor de interfa ță grafică cu
tehnologiile apărute a devenit o necesitate și a dus și ea la o serie de modific ări aduse
pachetelor.
2.10.1 Pachetul java.swing
Paleta mai largă de facilită ți ale pachetului Swing reprezint ă un motiv sufiecient
pentru a opta pentru acest pachet la dezv oltarea unei interfe țegrafice, însă existen ța AWT este
încă justificată datorită claselor mo ștenite de clasele pachetulu ijava.swing.
Dezvoltarea unei interfe țe grafie se reduce la utilizarea urm ătoarelor elemente:
Container; reprezintă componente care pot conține alte , cum ar fi Panel -uri,
DialogBox -uri etc.
Componente; reprezintă elementele de bază ale interfe ței cum ar fi butoane,
liste de derulare, meniuri etc.
LayoutManager ; reprezintă obiecte care definesc modul în care sunt aranjate
(dispuse) componentele într -un conta iner. Administratorul de dispunere nu este
vizibil într -o interfață, însă sunt vizibile rezultatele „muncii” sale. Dispunerea
componentelor interfeței este de mai multe feluri: dispunere secvențială,

Facultatea de Automatica si Calculatoare U.P.T.
21
dispunere tabelară, dispunere marginală sau dispunere ta belară
neproporțională.
Clasa abstractă Component este derivată direct din clasa Object și definește propriet ățile
fundamentale cât și metodele comune tuturor componentelor grafice, constituind baza de
derivare a componentelor concrete. Componentele conc rete ale pachetului java.swing pot fi
clasificate astfel[1]:
Componente atomice:
JLabel, JButton, JCheckBox, JRadioButton, JToggleButton, JScrollBar, JSlider,
JProgressBar, Jseparator
Componente complexe:
JTable, JTree, JComboBox, JSpinner, JList, JFileC hooser, JColorChooser,
JoptionPane
Componente pentru editare de text: JTextField, JFormattedTextField, JPasswordField,
JTextArea, JEditorPane, JtextPane
Meniuri:
JMenuBar, JMenu, JPopupMenu, JMenuItem, JCheckboxMenuItem,
JradioButtonMenuItem
Containere i ntermediare ;reprezintă suprafețe de afișare cu ajutorul cărora pot fi
organizate mai eficient componentele aplicației, putând fi imbricate.
JPanel are aceeași funcționalitate ca și clasa Panel din AWT, fiind folosit pentru
gruparea mai multor componente Swing și plasarea lor împreună pe o altă suprafață de
afișare. Gestionarul de poziționare implicit este FlowLayout, acesta putând fi schimbat
însă, chiar în momentul construirii obiectului JPanel, sau ulterior cu metoda setLayout.
Adăugarea de componente s e realizează ca pentru orice container, folosind metoda
add( ).
JScrollPane este o clasă foarte importantă în arhitectura modelului Swing, deoarece
oferă suport pentru derularea pe orizontală și verticală a componentelor a căror
reprezentare completă nu în cape în suprafața asociată, nici o componentă Swing
neoferind suport intrinsec pentru această operație.
Clasa JComponent este superclasa tuturor componentelor Swing, mai puțin a celor
care descriu containere de nivel înalt JFrame, JDialog, JApplet. Deoarec e JComponent
extinde clasa Container, deci și Component, ea moștenește funcționalitatea generală a
containerelor și componentelor AWT, furnizând bineînțeles și o serie întreagă de noi
facilități. Exemple :
JPanel, JScrollPane, JSplitPane, JTabbedPane, JDes ktopPane, JtoolBar
Containere de nivel înalt ; Pentru a fi afișate pe ecran componentele grafice ale unei
aplicații trebuie plasate pe o suprafață de afișare (c ontainer). Fiecare componentă
poate fi conținută doar într -un singur container, adăugarea ei pe o suprafață nouă de
afișare determinând eliminarea ei de pe vechiul container pe care fusese plasată.
Deoarece containerele pot fi încapsulate în alte container e, o componentă va face parte
la un moment dat dintr -o ierarhie. Rădăcina acestei ierarhii trebuie să fie un așa numit
container de nivel înalt, care este reprezentat de una din clasele JFrame, JDialog sau
JApplet.
În general orice aplicație Java independ entă bazată pe Swing conține cel puțin un
container de nivel înalt reprezentat de fereastra principală a programului, instanță a
clasei JFrame. Exemple: JFrame, JDialog, JWindow, JInternalFrame, JApplet

Facultatea de Automatica si Calculatoare U.P.T.
22
2.10.2 Caracteristicile componentelor grafice
Pentru a utiliza eficient obiectele complexe ale pachetelor grafice trebuie cunoscute
proprietățile principale ale acestora , cum ar fi:
Poziția; exprimat ă în sistemul de coordonate al container -ului
Numele; care este re ținut ca String
Dimensiunea; valori le lungimii și a l ățimii
Culoare foreground -ului
Culoare background -ului
Fontul folosit
Forma cursorului care este folosită la trecerea mouse -ului deaspura componentei
Vizibilitatea; standard orice componentă este vizibilă, dar dacă proprietatea a fost
setată pe valoare „false”, componenta nu va fi afi șată pe ecran
Majoritatea acestor atribute sunt setate sau ob ținute prin metode de tip get/set sau prin
folosirea claselor specializate pentru stabilirea dimensiunilor (Toolkit, Dimension, etc.)
[Jur06]

Facultatea de Automatica si Calculatoare U.P.T.
23
Capitolul 3 .Specifica țiile aplicației
3.1Structura generală a fun ționalit ății aplicației
Aplicația, pe partea de client, începe prin introducerea în bara de adrese a unui
browser, ce oferă suport pentru Java, a URL -ului paginii HTML care c onține applet -ul
responsabil cu ini țializarea aplicației -client și cu afișarea și controlarea interfe ței grafice.
Toate etapele aplica ției se pot urm ări în figura 5, urmând ca apoi să fie explicate
corespunzător.
Fig. 5 Etapele aplicației
Când applet -ul a fost încărcat complet se afi șează formularul de logare utilizatorului.
Aplicația-client va transmite aplica ției-server Username -ulși parola introdus ă de către
utilizator și va aștepta rezultatul autentific ării utilizatorului. În cazul în care acest a rezultat
este negativ se va reafi șa formularul de logare pentru a obține alte detalii de autentificare din
partea utilizatorului.
În momentul în care utilizatorul a reu șit să se autentifice îi vor fi afi șate informațiile
privind numărul de jucători de l a fiecare masă și va fi interogat asupra obțiunii de mas ă unde
dorește s ă joace. În pasul următor, aplica ția de pe partea de server va analiza îndeplinirea
condițiilor necesare pentru ca utilizatorul s ă poată începe jocul. Aceste condi ții presupun
existențaa minim doi jcători la masă. Dacă există deja un număr de minim doi jucători la
masa aleasă, utilizatorul va a ștepta terminarea rundei aflate în desf ășurare, iar în urm ătoarea
rundă va fi inclus joc. Dacă nu există nici un jucător la masa aleasă, utiliza torul trebuie să
aștepte sosirea unui alt juc ător.

Facultatea de Automatica si Calculatoare U.P.T.
24
Odată ce au fost îndeplinite condi țiile minime de joc se va începe o nou ă rundă de joc.
Începerea unei runde presupune transmiterea a două car ți fiec ărui jucător de la masă. Obie ctul
responsabil cu desfă șurarea jocului va cere aplica ției-client reactualizarea interfe ței grafice,
astfel încât să îi fi puse la dispozi ției utilizatorului opțiunile de joc despre care se va vorbi în
subcapitolul următor. Utili zatorul alege ac țiune dorit ă, iar aceasta este tran smisă obiectului
desfă șurării jocului. Runda de joc, având mai patru etape diferite, va repeta această interogare,
în cazul în care utilizatorul nu iese din runda de joc sau nu părăse ște masa. La finalul rundei
va fi ales câ știgătorul, urmând să înceapă o nouă rundă de joc. Conceptele jocului cât și
opțiunile de joc vor fi explicate în subcapitolul urm ător.
3.2 Funcționalitatea clientului și scurt ă prezentare a conceptelor
jocului
Funcționalitatea clientului poate fin împ ărțită în două categori: func ționalitate necesară
începerii jocului și funcționalitatea necesar ă desfă șurării jocului. Tot aici se va explica și
conceptul jocului de Poker de tip Texas Hold’em.
3.2.1 Conceptele jocului de Poker Texas Hold’em
Jocul se desfă șoară pe parcursul a patru etape , fiecare incluzând propria rundă de pariere.
În fiecare etapă jucatorul, în momentul când el este cel ce trebuie să parieze are la dispozi ție
următoarele ac țiuni:
Fold; reprezintă ac țiunea prin care juc ătorul anun ță că se retrage din rundă și nu mai
poate concura pentru jetoanele introduse în pot (suma tuturor pariurilor făcute de
jucători)
Check; reprezintă ac țiunea prin care juc ătorul î și exprim ă dorința de a trece la
urmatoarea etapă fară a mai depune jetoane în pot. Condi ția necesar ă acestei ac țiuni
este ca nici un jucătora aflat înaintea celui curent să nu fi pariat.
Call; reprezintă ac țiunea prin care juc ătorul depune jetoanele necesare, cerute de alt
jucător printr -un pariu, în pot pentru a rămâne în competi ție.
Bet; reprezintă ac țiunea prin care juc ătorul pariază jetoane pentru a obliga ceilal ți
jucători să mai contribui e cu jetoane la pot sau de a renun ța la competiția pentru pot al
acestei runde.
Raise; reprezintă ac țiune prin care juc ătorul măre ște pariul/pariurile (BET) făcute de
alți juc ători.
Etapele jocului men ționate sunt:
Preflop; fiecare jucător prime ște dou ă carți pe care doar el le poate vedea, urmând ca
fiecare să î și exprime acțiunea pentru continuarea la etapa urm ătoare
Flop; se pun trei car ți, cu fața în sus, în mijlocul mesei, astfel încât fiecare să le poată
vedea, urmând iara și o rund ă de pariere.
Turn; se mai pune o carte langă cele din flop cu acelea și condiți, urmând o rund ă de
pariere.
River; se a șeazăși ultima carte a jocului în mijlocul mesei în aceleași condiți care
primele p atru. După ce se termină ultima rundă de pariere,jucătorii răma și în joc își
arată cărțile (termen numit Showdown) și juc ătorul care formează cea mai bună mână
de Poker din cele cinci căr ți de jos împreun ă cu cele două din mână, câ știgă runda
împreună cu p ot-ul strâns în toate etapele rundei. [Rub10]

Facultatea de Automatica si Calculatoare U.P.T.
25
3.2.2 Funcționalitatea necesar ă începerii jocului
Se referă la ansamblul de func ționalitate necesar utilizatorului pentru a ajunge în
postura de jucător la o masă. Aceste fuc ționalit ăți sunt:
Autentifica rea utilizatorului (Login); orice jucător trebuie autentificat pentru a putea
participa la joc
Alegerea mesei; utilizatorul poate vizualiza câ ți jucatori exist ă la fiecare masă și pot
alege masa căreia doresc să i se alăture
Logout; utilizatorul parase ștesistemul utilizând func ția logout
Toate aceste func ții sunt necesare utilizatorului din momentul accesului în sistem pân ă la
șezarea la masă.
3.2.3 Funcționalitatea necesar ă desfă șurării jocului
Acest ansamblu de func ționalitate este necesar utilizatorul ui pentru a putea participa la
desfă șurarea corect ă a jocul ui. Mai jos găsim lista acestor ac țiuni în termenii explicați mai
devreme în acest capitol.
Fold
Check
Call
Bet
Raise
3.3 Interfa ța grafic ă a utilizatorului
Aplicația de pe partea de client pr ezentată este concepută sub forma unui Japplet
inclus într -o pagina HTML care îi stabile ște proprietatea de codebase. La accesarea paginii
.html se va încărca applet -ulși se va afișa formularul de autentificare a utilizatorului prezentat
și în figura 6 d e mai jos.
Fig. 6 Formularul de autentificare

Facultatea de Automatica si Calculatoare U.P.T.
26
Odată ce utiliazatorul introduce detaliile de autentificare, acestea vor fi transmise către
server și se va aștepta rezultatul autentific ării. În cazul în c are utilizatorul reprezintă un client
valid ,se trece la alegerea mesei unde acesta dore ște să joace. În cazul în care la masa aleasă
de către utilizator nu se mai regăse ște momentan nici un alt juc ător, va fi afi șat un mesaj,
conținând textul „Waiting for other players to join” ca în figura 7, pân ă în m omentul a șezării
la masă a unui alt jucător.
Fig. 7 Mesajul de a șteptare al interfeței grafice
Dacă se regăse ște minim un juc ător la masă, jocul va începe instant. Un jucător va
vedea propriile sale două căr ți cât și cele cinci c ărți comune. C ărțile ad versarilor vor fi afi șate
doar dacă ace știa nu au ieșit din rund ă, iar acestea vor fi afi șate cu spatele evident. Singurul
moment în care unul sau mai mul ți juc ători văd car țile unui adversar este când acel adversar
este stabil it ca fiind câ știgătorul rund ei, iar în acel caz i se vor arăta căr țile și celorlalți
jucători. Tot în acest moment, va fi afi șat deasupra mesei de joc și mâna de Poker cu care
acesta a câ știgat.
În partea de sus a mesei poate fiecare jucător sa vadă care este mâna de Poker pe care
odeține. Aceasta se va calcula atât preflop cât și pe flop, turn și river pentru a oferi
jucătorului informa țiile necesare deciziei de a continua în acea rund ă.
Fiecare jucător poate vedea ce au făcut adversarii săi sub forma unor mesaje text
afișate in fe reastra din stanga jos. Fereastra are implementată și o bar ă de navigare pentru a
putea vedea ce s -a întamplat în mâinele anterioare, cum ar fi, cine a câ știgat acum câteva
runde, cine a plusat, cât a plusat, și așa mai departe. În momentul când un juc ător renunță
carțile sale nu vor mai fi afișate, cum este în cazul lui Andrei în figura 8. Tot în acea figur ă
putem observa și butoanele Fold, Check, Bet cât și slider -ul pe care le are afi șate Maria.
Butoanele apar doar acelui jucător care trebuie să ac ționez e, putând opta pentru
Fold,Check/Call sau Bet/Raise. În cazul în care se dore ște parierea se folosește slider -ul
pentru a stabili cantitatea.

Facultatea de Automatica si Calculatoare U.P.T.
27
Fig.8 Interfa ța grafic ă a jocului
Fereastra interfe ței grafice a utilizatorului este un JFrame, reținut ca atribut în clasa
ClientFrame. Pe lângă acesta, clasa, mai de ține o serie de atribute dup ă cum urmează:
topPanel; un obiect de tip JPanel care reprezintă container -ul tuturor butoanelor de tip
JButton, a ferestrei din stânga jos care este un obiect JTextAr ea învelit într -un
JScrollPane , a tuturor JLabel -urilor (numele jucătorilor, numărul jetoanelor, tipul
mâinii) și a slier -ului de tip JSlider
cardpainter; reprezintă un obiect al clasei CardPainter care extinde clasa JPanel și a
cărei func ți este de a dese na masa, căr țile și tabletele -suport pentru nume și num ărul
de jetoane.
Call, fold și raise; reprezint ă butoanele de tip JButton responsabile pentru alegerea
opțiunii dorite. Acestea sunt afișate doar când este rândul juc ătorului să ac ționeze.
Names[9]; re prezintă un tablou de JLabel -uri care afi șează numele jucătorilor de la
masă
Chip[9]; reprezintă tot un tablou de JLabel -uri care afi șează numărul de jetoane al
fiecărui jucător
cardInfo; reprezintă un JLabel care afi șează ce fel de mână de Poker de ține ju cătorul.
Acesta este reactualizat la fiecare etapă a unei runde
slider; reprezintă un obiect de tip JSlider care permite jucătorului să stabilească
cantitatea de jetoaane pe care dore ște să o parieze. Acest obiect este reactualizat după
fiecare rundă pentr u a afi șa corect limitele crescute sau mic șorate datorit ă câștigării
sau pierderii unei mâini
result; reprezintă JLabel -ul care afi șează la sfâr șitul rundei câștig ătorul și mâna cu care
acesta a câ știgat

Facultatea de Automatica si Calculatoare U.P.T.
28
Imaginea din fundal este desenată prin ob ținerea unu i obiect de tip layerPane din JFrame -ul
principal și ad ăugarea unui JLabel, care conține imaginea, pe cel mai adânc strat al acestui
layerdPane. Următorul strat îl reprezintă JPanel -ul cardpainter care, precum spus va afi șa
masa, căr țile și tabletele -supor t. Stratul de la suprafa ță este constituit din obiectul topPanel
care deține, precum zis anterior, butoanele, numele juc ătorilor, numărul jetoanelor, etc.
Obiectul ClientFrame este reactualizat, de către clasa care implementează interfa ța la
distanță a cl ientului, prin intermediul unei metode numite setTableInfo care prime ște, de la
obiectul responsabil cu desfă șurarea jocului, numărul etapei unei runde, un tablou ce con ține
numele jucătorilor, un tablou ce con ține num ărul jetoanelor fiecăruia, căr țile ce urmează a fi
afișate și num ărul ce reprezintă indexul jucătorului din tablourile anterioare.
Toate imaginile folosite se extrag de dintr -un director de lucru de pe server, iar acestea
sunt:
imaginea de fundal
imaginea din ecranul de a șteptare a unui juc ător
cele 52 de imagini, una pentru fiecare carte din pachetul de căr ți
tabletele -suport pentru nume și pentru num ărul de jetoane
Pagina HTML men ționat ă anterior con ține strictul necesar rul ării aplica ție pe partea de client:
<HTML>
<title> OnlinePoker </titl e>
<center> <h1> Welcome to Black Sea Poker </h1> </center>
<applet codebase ="http://192.168.0.101/bin/"
code ="ClientStarter.class"
width =260 height =350>
</applet>
</HTML>
Codul pagini con ține doar un tag de tip applet în care se stabilește proprietatea de t ip
codebase, adică unde se găsesc clasele necesare rulării applet -ului cât și codul care se va
executa, anume clasa ClientStarter.class.
Posibilitatea rulării aplica ției direct din browser -ul personal reprezintă un avantaj mare
pe care îl de ține aplicația față de aplica ți asem ănătoare care necesită instalare. Aplica țile de tip
„no download” devin foarte apreciate printre utilizatorii de rând a acestor servicii. În
capitolele următoare va fi subliniată proprietatea aplica ției de tip „no download” și avantaj ele
acesteia.

Facultatea de Automatica si Calculatoare U.P.T.
29
Capitolul 4. Proiectarea aplica ției
4.1 Mediul de lucru Eclipse IDE for Java EE Developers
Eclipse integrated development environment for Java Enterprise Edition Developers
pune la dispozi ție proiectelor sale tool -uriși framework -uri absolut necesare dezvoltării
software, pornind de la modelare, dezvoltare și raportare pân ă la testarea și profilarea
aplicațiilor. Întreaga gam ă este bazată pe proiectare și implementarea aplicaților Java
Enterprise Edition câtși a apli caților și serviciilor Web. Eclipse folosește plugin -uri pentru a
furniza întreaga sa func ționalitate, iar mecanismul de plugin -uri reprezi ntă un framework
bazat pe implementarea pe componente. În afară de kernel -ul Eclipse, totul reprezintă un
plugin, iar astfel toată func ționalitatea este creat ă în aceea și manier ă. Exemple de plugin -uri
Eclipse se întind de la plugin -uri UML până la cele pentru explorarea bazelor de date sau a
analizei de cod. Plugin -urile adiționale folosite în versiunea Eclipse IDE for Java EE
Developers în acest proiect au fost plugin -ul pentru Remote Method Invocation pentru a u șura
dezvoltarea aplica ției, nefiind necesare pornirea manual ă a registrului RMI sau compilarea
folosind compilatorul RMIC pentru ob ținerea Stub -urilor și a Sch eleților, cât și plugin -ul
inCode pentru îmbunătă țirea calit ății design -ului aplica ției.
4.2 Arhitectura aplica ției
Aplicația prezentat ă, precum am precizat și în capitolul Introducere, este proiectat ă pe
baza unei arhitecturi de tip client -server three -tier. Aplica ția este astfel împ ărțită în două
proiecteși un set de interfețe la distanț ă ce trebuie să fie accesibile proiectelor. Avantajul adus
aplicației, din acest punct de vedere, const ă în posibilitatea de a compila doar aplica ția-client
sau cea pe parte de server, în func ție de modific ările aduse vreuneia dintre ele.
Pentru a oferi o privire de ansamblu asupra aplica ției prezentate, trebuie scoase în
evidență caracteristicile de proiectare a celor două proiect cât și a setului de interfețe la
distanță.Edificatoare, din acest punct de vedere, este și diagrama de clase din figura 9.
4.3 Proiectare de detaliu a aplica ției
4.3.1 Proiectarea aplicației pe partea de s erver
Proiectul păr ții de server a aplicației cuprinde mai multe pachete Java care grupează
diferitele func ționalit ăți. În pachetul de baz ă a proiectului regăsim clasa ServerStarter care
este responsabilă de stabilirea comunica ției între server și client pe baza tehnologiei Remote
Method Invocation (RMI). Un alt pachet îl reprezintă gam elogic care con ține clasele necesare
logicii jocului . Logica jocului a fost proiectată astfel încât fiecare obiect Table să creez o
instanță a unui obiect de tip Game, care extinde clasa Thread, și să îl lanseze în execu ție. La
lansarea server -ului se vor crea cinci mese diferite, fiecare avănd lansând propriu fir de
execuție. Clasa Game deține responsabilitatea de a controla desf ășurarea jocului la o mas ă
prin verificarea condi țiilor minime de demarare a jocului și prin organizarea etapelor de joc în
ordin ea corespunzătoare. Tot clasei Game îi sunt atribuite sarcinile de a ini țializa interfața
utilizatorului prin transmiterea detalilor mesei catre fiecare jucător în parte, cât și
managementul corespunzător al jucătorilor afla ți la mas ă. Pentru toate acestea , clasa Game

Facultatea de Automatica si Calculatoare U.P.T.
30
folose ște clasele existente în pachetul gamelogic, cum ar fi clase pentru reprezentarea
pachetului de căr ți, a unei singure c ărți, a unei etape corespunz ătoare unei runde etc. Precum
și clasele din pachetului player care au rolul de a reprezen ta jucătorii mesei: Player,
TablePlayer, GamePlayer.
Un alt pachet este server.rmi care con ține implementarile interfețelor la distanț ă de pe
partea de server care vor fi discutate la nivel de implementare în capitolul următor, dar o
scurtă prezentare a a cestora este :
clasa RemoteLoginImpl; implementarea procesului de autentificare pe parte de server
clasa RemoteLobbyImpl; implemetarea Lobby -ului unde utilizatorul poate ob ține
informații despre mese și unde acesta alege masa la care dorește s ă joace
clasa RemoteServerImpl; implementarea necesară procesului de logout cât și el de
obținere a obiectului la distanț ă Lobby de către client
clasa RemoteTableImpl; implementează procesul de a șezare la mas ă a unui utilizator
Un ultim pachet este server.util care este încă în stadiul de proiectare, dar va de ține
implemenatrea procesului de autentificare folosind datele din baza de date.
4.3.2 Proiectarea aplica ției pe partea de client
Partea de client a aplica ției este proiectat ă ca un applet ce se incarcă și ruleaz ă într -o
pagină HTML. Pagina html va încărca clasa ClientStarter, care are rolul de a afi șa interfața cu
utilizatorul și de a stabili comunicarea cu partea de server a aplicației distribuite. ClientStarter
este o clasă care extinde JApplet și afișeaz ă form ularul de înregistrare. Tot aici, se vor ob ține
și instanțele obiectelor la distanț ă. Primul astfel de obiect se va ob ține prin metoda lookup()
de la registrul RMI ce rulează pe server. Următoarele instan țe se vor obține, prin valori
returnate ale metodelo r la distan ță, pe parcurs ce utilizatorul înaintează spre a șezarea la mas ă
și începerea jocului. Tot clasa ClientStarter afi șeazăși JFrame -ul ce conține masa de joc.
Tot clasa ClientStarter implementează și exportarea obiectului la distanț ă
RemoteClient , care va fi invocat de server pentru a ob ține acțiunile dorite de utilizatori în
decursul jocului. Astfel, aplica ția client devine server, iar server -ul devine client, deoarece
partea de server este cea care invocă la distan ță metode asupra obiectului la distanță de pe
partea de client în timpul desfă șurării jocului. Aceasta a făcut posibilă utilizarea modelului
obbserver -observable, adesea folosit în aplia țiile distribuite din zilele noastre. Modelul
precizat con ține la baz ă metoda update() a obiectului c lient care implementează interfa ța la
distanță. Astfel, clientul se înregistrează în sistem, iar în momentul începerii jocului,
informațiile necesare reactualiz ării propriei interfe țe grafice sunt obținute din invocarea
metodei update() de catre modulul se rver.
Interfața grafic ă a utilizatorului este controlată și reactualizat ă de clasele din pachetul
rmi al proiectului client și anume clasele ClientFrame și CardPainter.
4.3.3Proiectarea interfe țelor la distanț ă
Interfețele la distanț ă proiectate se î mpart în două categori și anume cele care sunt
implementate pe partea de server și cea implementat ă pe partea de client. Interfe țele vor fi
prezentate în ordinea în care acestea sunt folosite în decursul aplica ției.
Interfața la distanț ă RemoteLogin repre zintă interfa ța implementat ă pe partea de server
de obiectul RemoteLoginImpl. Partea de client a aplica ției va obține referința din registrul
RMI. Interfa ța prezint ă metoda:
public RemoteServer login(String username,String passHash) throws
UnknowUserExc eption, RemoteException;

Facultatea de Automatica si Calculatoare U.P.T.
31
În această metodă sunt transmise detaliile de autentificare ale utilizatorului și este returnat ă o
instanță RemoteServer .
Interfața la distanț ă RemoteServer este implementată pe partea de server de clasa
RemoteServerImpl și prezi ntă metodele:
public void logout() throws RemoteException;
public RemoteLobby getLobby() throws RemoteException;
public RemoteCashier getCashier() throws RemoteException;
din metoda getLobby() ob ține clientul referința RemoteLobby necesa ră afi șării meselor și
alegerea unei mese.
Interfața la distanț ă RemoteLobby este implementată pe server de clasa
RemoteLobbyImpl și conține metodele:
public List<TableInfo> getTableInfos() throws RemoteException;
public RemoteTable joinTable( inttableId, RemoteClient client) throws
RemoteException;
din această metodă se ob ține referința RemoteTable
Interfața la distanț ă RemoteTable con ține metoda
public void sitIn( intbuyIn) throws RemoteException;
prin care se face a șeazarea la mas ă.
Interfațala distanță RemoteClient este implementată pe partea de client de clasa
RemoteClientImpl și conține un numar mai mare de metode definite decât ccelelalte interfețe
datorită faptului ca trebuie să satisfacă interogare clientului asupra ac țiuniilor care dor ește să
la interprindă în timpul jocului.
public void giveCards(String first, String second, int
playerNumber) throws RemoteException;
public void giveFlop(String first, String second, String third)
throws RemoteException;
public void giveTurn(String t urn) throws RemoteException;
public void giveRiver(String river) throws RemoteException;
public Event promptAction( intt)throws RemoteException;
public void update(String gameStat, intplayer, intchips,
String name) throws RemoteException;
public voidsetWinner( intplayerNumber,String card1,String
card2) throws RemoteException;
public intgetBet() throws RemoteException;
metodele giveCards(…), giveFlop(…),giveTurn(..) și giveRiver(…) definesc acțiunile prin care
sunt transmise cele două car țiprivate a jucătorului cât și celelalte cinci c ărți comune c ătre
client. Metoda promptAction(…) are rolul de a informa clientul că este rândul său să ac ționeze
și că trebuie să hotărască ce ac țiune dorește s ă interprindă. Metoda update(…) de ține
comport amentul unui Listener și are rolul de a inițializa și reactualiza interfața grafic ă a
utilizatorului. Metoda setWinner(…) anun ță câștigătorul rundei și furnizeaz ă informa țiile
necesare interfe ței grafice pentru a desemna câștig ătorul corespunzător.

Facultatea de Automatica si Calculatoare U.P.T.
32
Fig.9 Diagram claselor aplica ției

Facultatea de Automatica si Calculatoare U.P.T.
33
Capitolul 5. Implementarea codului pe partea de server
Urmărind structura diagramei de clase din figura 9, putem împăr ți dup ă funcționalitate
codul de pe partea de server a aplica ției. Astfel, vom avea urm ătoarele module :
inițializarea comunicației prin RMI și lansarea în execuție a meselor de joc
logica jocului
managementul jucătorilor
servciile la distan ță pose la dispozi ție clientului
utilitare
În următoarele subcapitole, se va face o scurtă prezentare a implementării claselor esen țiale.
5.1 Clasa ServerStarter
Clasa ServerStarter con ține doar metoda main() . Acestă metodă începe cu instalarea
managerului de securitate care va utiliza poli ța de securitate prezent ă în fi șierul de lucru al
proietului aplica ției:
if(System.getSecurityManager () == null){
System .setSecurityManager (newRMISecurityManager());
}
Următorul pas îl reprezintă crearea unei instan țeRemoteLogin lc = new
RemoteLoginImpl(); reprezentând obietul la distan ță ce oferă ini țializarea serviciului de
autentificare. Această referire trebuie întâi exportată folosind metoda exportObject(Object) al
clasei UnicastRemoteObject despre care sa discutat în capitolul fundamentării teoretice a
tehnologiei RMI:
try{
lc = (RemoteLogin)UnicastRemoteObject. expo rtObject (lc);
Naming. rebind ("rmi://192.168.0.101/RemoteLogin" , lc);
}catch (RemoteException e) {
e.printStackTrace();
}catch (MalformedURLException e) {
e.printStackTrace();
}
Odată ce obiectul a fost exportat se va trece la înregistrarea acestuia în registrul RMI, care
obligatoriu rulează pe aceea și mașin ă cași aplicația server. S -a folosit metoda rebind(…)
pentru a asigura că, în momentul în care se lansează aplica ția, chiar dac ă există un obiect cu
numele RemoteLogin deja înregistrat, acesta va fi șters și înlocui cu actuala referire.
Blocul try -catch este obligatoriu, deoarece metodele pot genera excep țiile
RemoteException, o excep ției generat ă de orice metodă implicată în procesul de invocarea la
distanță, câtși excepția MalformedU RLException care indică, de obicei, o eroare în șirul de
caractere care reprezintă URL -ul obiectului unde va fi publicat.
În final se va apela metoda statică a clasei Lobby getInstance(), pentru a ob ține
instanța singleton -ului Lobby. Pe singleton -ul Lob by se va apela metoda setUpTables() pentru
a lansa cele cinci fire de execu ție de tip Game ale celor cinci obiecte Table.
În concluzie, acesta clasă a instalat managerul de securitate, a înregistrat primul obiect
la distanță in registrul RMI, pentru a put ea fi obținut de c ătre client, și a lansat în execuție
mesele de joc. Din punct de vedere al aplica ției server, se pot aștepta deja conexiuni ale
clienților.

Facultatea de Automatica si Calculatoare U.P.T.
34
5.2 Pachetul gamelogic
5.2.1 Clasa Game
Cea mai importantă clasă a pachetului gamelogic este clasa Game. Aceasta extinde
clasa Thread și este lansat ă în execu ție de obiectul Table căreia îi apar ține. Atribute clasei sut
următoarele:
CopyOnWriteArrayList <GamePlayer> waitingPlayers; reprezintă tabloul ce
conține juc ători care doresc să se alăture me sei dar trebuie să a ștepte s ă se termine
runda în desfă șurare sau s ă se elibereze un loc la masă, dacă aceasta este plină.
ArrayList<GamePlayer> currentPlayers ;reprezintă tabloul ce con ține juc ători
unei mese
Pot; un întreg care reprezintă suma tuturor je toanelor pariate într -o rundă. Acesta va fi
inițializat cu zero la începutul fiecarei runde.
Deck deck; reprezintă un obiect de tip Deck care implementează serviciul de generare
aleatoare a unor obiecte de tip Card. Practic acesta stabile ște c ărțile care s unt trimise
către clien ți
Metoda run() a firului de execu ție Game reprezint ă implementarea desfă șurării jocului, care
rulează cât timp firul nu este terminat de închiderea mesei. Toate instruc țiunile metodei sunt
înfașurate într -o clauză if care verifică d acă există minim doi jucători la masă. Această cluază
if este înfă șurat ă la rândul ei, alături de o metodă refreshPlayers() care are rolul de a
reactualiza tablourile jucătorilor, într -o buclă while care se execută la infinit.
Inițializarea e tapeipreflop presupune ini țializarea interfeței grafice a utilizatorilor cât
șia obiectului de tip Deck:
initFrame();
this.pot=0;
deck.shuffle ();
intstop=0;
//runda PreFloop
Round preFloop = newRound(1, currentPlayers ,dealer ,deck);
preFloop.start(1);
this.pot+= preFloop.pot();
Etapa preflop începe prin crearea unui obiect de tip Round careia i se transmite ca parametru
numărul corespunzător etapei preflop cât și tabloul de juc ători, pozi ția dealer -ului pentru a
stabili ordinea jucătorilor, și obiectul dec k pentru a ob ține obiectele de tip Card necesare.
Dupa ce s -a executat runda prin metoda start() a obiectului Round, se va extrage valoarea pot –
ului prin metoda pot() al aceluia și obiect. Pentru a întelege cum și dac ă se trece la etapele
următoare vom urmă riși explica codul de mai jos.
if(nrPlayersInHand()>1){
//runda Floop
Round floop = newRound(2, currentPlayers ,dealer ,deck);
floop.start(2);
this.pot+= floop.pot();
}
else
{
WonByFolding();
stop=1;
}
if(nrPlay ersInHand()>1){

Facultatea de Automatica si Calculatoare U.P.T.
35
//runda Turn
Round turn = newRound(3, currentPlayers ,dealer ,deck);
turn.start(3);
this.pot+= turn.pot();
}
else
{
if(stop==0){
WonByFolding();
stop=1;
}
}
if(nrPlayersInHand()>1){
//runda River
Round river = newRound(4, currentPlayers ,dealer ,deck);
river.start(4);
this.pot+= river.pot();
}else
{
if(stop==0){
WonByFolding();
stop=1;
}
}
if(nrPlayersInHand()>1){
getWinner();
}
else{
if(stop==0){
WonByFolding();
stop=1;
}
}
După cum observăm etapele flop, turn șsi river au aceeași manier ă de execu ție ca și etapa
Preflop. În plus apar condi țiile înaintea fiec ărei runde de verificare numărului de jucători
răma șiîn rundă, deoarece în cazul în care acesta este 1, jucatorul rămas este desemnat
câștigător. Pentru a descrie procesul pe scurt putem spune ca se trece din etapa preflop în
etapa Flop, doar dacă mai avem minim doi jucători răma și în mân ă. Se va desfă șura etapa
Flop iar în cazul în care se îndeplinesc condi țiile necesare se trece la etapa Turn. Similar se
întampla și cu trecere din etapa Turn în etapa River. În aceasta ultim ă etapă, dacă după runda
de pariere mai avem minim doi jucători ca au rămas în mână se va trece la alegerea
câștigătorului, apelând metoda getWinner(). În aceasta metodă se ob ține c ărțile juc ătorilor
răma și în mân ăși se creaz ă obiecte de tip Hand care vor stabili care mână de Poker este mai
puternică, desemnând câ știgătorul. În momentul în care se știe care este câștig ătorul rundei,
acestuia i se vor aduna jetoanele din pot, numărului jetoanelor personale.
Metode initFrame() are rolul, precum s -a precizat mai devreme, să ini țializeze interfața
grafică a utilizatorilor. Aceasta se face pr in transmiterea clien ților, prin intermediul metodei
update(…) a fiecăruia, numele și num ărul de jetoane al fiecărui jucător pentru a putea fi afi șate
în GUI.

Facultatea de Automatica si Calculatoare U.P.T.
36
5.2.2 Clasa Round
Clasa Round reprezintă implementarea etapelor jocului. Aceasta descrie
comportamentul etape pe baza unui număr al etapei trimis ca parametru de obiectul Game. În
metoda start(int round) avem:
{
if(TwoPlayersInHand())
{
sendCardsToPlayers();
sendCardInfo(round);
setActedAll();
betting();
resetPlayerBet();
}
}
Clauza if verifică și ea existanța a minim doi juc ători răma și în mân ă. Metoda
sendCardsToPlayers are rolul de a implementa extragerea unor obiecte de tip Card
aleatoare,folosind un obiect Deck trimis ca parametru constructorului clasei. Astfel, pen tru
etapa Preflop, folosind obiectul Deck, se vor crea două obiecte de tip Card aleatoare pentru
fiecare jucător. Transmiterea căr ților c ătre clienți se face prin invocarea la distanț ă a metodei
giveCards(…) al obiectului la distan ță ce implementează i nterfața RemoteClient:
try{
players .get(i).getRemoteClient().giveFlop(c1.toString(), c2.toString(),
c3.toString());
}catch (RemoteException e) {
e.printStackTrace();
}
Blocul try -catch este menit să prindă o excep ției de tip RemoteException c e poate fi generată
de invocarea la distan ță a metodei giveCards(…). Atributul players reprezintă tabloul de
jucători primit ca parametru de constructorul clasei, iar metoda getRemoteClient () va returna
referirea la obiectul la distan ță al clientului din poziția indicelui i al tabloului.
Metoda sendCardInfo() este responsabilă pentru transmiterea către clien ți a tipului de
mână de Poker pe care îl de țin în etapa respectiv ă. Acest lucru se realizează prin crearea unui
obiect de tip Hand care prime ște ca ș i pramametri obiectele de tip Card al jucătorului, atât cele
personale cât și cele comune tuturor juc ătorilor. Clasa Hand va fi descrisă în subcapitolul
următor, unde se va eviden ția și relația acesteia cu clasa HandEvaluator care calculeaz ă tipul
unei mâi ni de Poker.
Fiecare jucător de ține un flag, care arat ă dacă acel jucător a ac ționat sau dac ă mai
trebuie să ac ționeze. Deasemenea avem și un flag care s ă desemneze starea de „în mână” a
fiecărui jucător. Metoda setActedAll(), din metoda start(), are rolu l de a reseta aceste flag -uri,
fiecare jucător devenind astfel eligibil pentru a ac ționa.
Metoda betting() este cea mai complexă metodă a clasei și conține implementarea unei
runde de pariere:
{
if(players .get(i).getInHand()==1 && players .get(i).getActed ()==1)
{
try{
if((lastManStanding )!=1){
if(players .get(i).getChips()>0)
e =players .get(i).getRemoteClient().promptAction( bet);
else e = newEvent( "Call" );

Facultatea de Automatica si Calculatoare U.P.T.
37
}else {
e = newEvent( "Call" );
}
System. out.println( "Lastman standin is : " +
lastManStanding );
}catch (RemoteException e1) {
//TODO Auto-generated catch block
e1.printStackTrace();
}
if(e.info.compareTo( "Fold" )==0) {
fold(i);
lastManStanding –;
System. out.println( "Lastman standin is : " +
lastManStanding );
}
if(e.info.compareTo( "Call" )==0) call(i);
if(e.info.compareTo( "Raise" )==0) raise(i);
}
}
Metoda parcurge tablou de jucători, verificand dacă jucătorul curent este „î n mână” și nu a
acționat înc ă. În caz afirmativ, se verifică daca jucătorul curent nu este cumva ultimul jucător
ramas în mână, deoarece asta ar însemna că acesta a câ știgat runda. Urmeaz ă verificare
numărului de jetoane care trebuie să fie pozitiv pentru a fi eligibil să ac ționeze. Urm ătorul pas
este obținerea referinței la distanț ă a clientului și transmiterea comenzi de a acționa prin
metoda promptAction(bet) care prime ște ca argument pariul care s -a făcut înaintea jucătorului
în cauză. Metoda va returna un eveniment, reprezentând ac țiunea aleas ă de către jucător. În
funcție de evenimentul returnat se va apela metoda corespnz ătoare ac țiune, trimițând ca
parametru indexul din tabloul de jucători al jucătorului în cauză.
Metodele fold(i), call(i), raise(i) sunt responsabile pentru setarea flag -urilor
corespunzătoare fiecărei ac țiuni. În cazul fold(i) se va marca jucatorul ca fiind ieșit din mân ă
pentru a actualiza interfa ța grafuc ă utilizatorilor și pentru a nu mai fi pus s ă acționeze când
urmează rândul s ău. Metoda call(i) setează flag -ul jucătorulu astfel incât să fie men ționat c ă
acesta a ac ționat și actualizeaz ă numărul de jetoane al acestuia, scăzând cât adupus în pot.
Metoda r aise(i) setează și ea flag -ul jucatorului ca „deja ac ționat” , actualizeaz ănumărul de
jetoane și stabilește noua valoare a pariului ce trebuie achitat de fiecare juc ător care urmeaază.
În finalul metodei start(…) se apelează metoda resetPlayerBet() pentru a reini țializa
valoarea pariului care trebuie achitat de fiecare jucător .
5.2.3 Clasele Hand și HandEvaluator
Clasa Hand este clasa care implementează reprezentarea unei mâini de joc. Acesta
deține ca și atribute un tablou de obiecte de tip Card, menit s ă dețină informa ți despre c ărți, și
un întreg care reprezintă rangul ac elei mâini. Rangul unei mâini, va fi explicat mai în detaliu,
în implementarea clasei HandEvaluator, dar reprezintă, în mare, ce fel de mână de Poker
reprezintă căr țile.Din punct de vedere a metodelor, clasa Hand, con ține mai multe metode
get/set menite s ă seteze sau să extragă informa țiile necesare legate de c ărțile pe care le
conține. Clasa, suprascrie și metoda toString() pentru a oferi o reprezentare corespunz ătoare,
conținănd cărțile și tipul mâinii, util ă interfeței grafice a utilizatorilor.
Constru ctorul clasei Hand prime ște ca parametru un tablou de obiect de tip Card, care
la rândul său, este dat ca parametru constructorului unui obiect HandEvaluator, creat în

Facultatea de Automatica si Calculatoare U.P.T.
38
constructorul clasei Hand. Următorul pas al constructorului clasei Hand este de a apela
metoda evaluateHand() a obiectului HandEvaluator nou creat, urmărind să ob ține valorile
necesare re ținute în atributele cards și rank.
Clasa HandEvaluator() con ține atributul cards, care este un tablou de șapte obiecte de
tip Card. În constructorul clasei se va atribui valoarea tabloului primit ca parametru atributului
cards. Ultima instruc țiune a constructorului este un apel la metoda sort(), care are rolul de a
sorta descrescător căr țile reținute în atributul cards.
Metoda evaluateHand() returnează un obiect de tip Hand căruia i s -a calculat rangul și
a cărui obiecte de tip Card au fost setate conform acelui rang. Practic, această metodă
evaluează cele maxim șapte c ărți primite și formeaz ă cea mai bună mână de Poker. Pentru a
stabili o anumită ordine a mâinilor de Poker acetea primesc ranguri, iar aceste ranguri sunt:
Rang 1 Carte Mare (High Card)
Rang 2 o pereche (one Pair)
Rang 3 două perechi (two pair)
Rang 4 trei bucă ți (Set)
Rang 5 Chintă (Straight)
Rang 6 Culoare (Flush)
Rang 7 Full House (Full Hou se)
Rang 8 Careu (Quads)
Rang 9 Straight Flush
Rang 10Chintă Roială (Royal Flush)
Pentru a ob ține acest rezultat, metoda evaluateHand() fo losește dou ă metode.
Hand h1 = getHand1();
Hand h2 = getHand2();
if(h1.getRank()>h2.getRank())
return h1;
else
return h2;
Prima metodă este getHand1(); reprezintă metoda care va verifica dacă din cele șapte c ărți se
poate forma o mână de Poker de tip careu, full huse, trei bucă ți, dou ă perechi, o pereche sau
nimic. Algoritmul metodei se bazează pe folosir ea unui tablou de apari ția cărților. Mai exact,
tabloul reține de câte ori apare un tip de carte (spre exemplu: asul apre de 2 ori, cinciul apare
de 3 ori, etc. )După ce a fost configurat tabloul de apari ți se stabilește rangul inițial ca fiind 1
și se tr ece la evaluarea apari ților. Testarea se face parcurgând tabloul de la cartea as, care
reprezintă numărul 14, la doiar. Carte se verifică dacă apare de patru ori, iar în caz afirmativ
se stabile ște rangul ca fiind opt. În caz negativ se verific ă dacă apare de trei ori cartea. Dacă
da, se verifică valoarea curentă a rangului:
În cazul rang=4 avem o mână de tip Full House și rangul va fi setat pe 7
În cazul rang=3 avem tot o mână de tip full, iar rangul a fi setat tot pe 7
În cazul rang=1 avem o mână tip tr ei bucăți iar rangul va fi setat pe 4
În fiecare caz se re țin și c ărțile care formeaz ă rangul cel mai mare pentru evaluare finală. În
cazul în care o carte appare de două ori procedăm aproape la fel:
În cazul rang=4 avem o mână tip Full House iar rangul de vine 7
În cazul rang= 2 avem o mână tip două perechi iar rangul devine 3
În cazul rang=1 ave o mână tip pereche iar rangul devine 2
Metoda reurnează la final un obiect de tip Hand care prime ște ca parametri rangul, prima și a
doua carte care formează mâna.
Cea de -a doua metodă getHand2() va evalua mâinile de tip Royal Flush, Straight Flush
Flushși Straight. Inițial se va seta rangul pe unu și se va reține într -un tablou de câte ori apare

Facultatea de Automatica si Calculatoare U.P.T.
39
o culoare printre căr țile primite ca parametru. În cazul în care apa re de minim cinci ori rangul
va deveni 6 și se rețin c ărți care dețin culoarea precizat ă. Dacă o culoare apare de m inim cinci
ori se va verifica dacă căr țile sunt dețin numere consecutive, deoarece în caz afirmativ se va
obține o mân ă de tip Straight Flush , rangul devenind 9. Dacă acesta este cazul, se verifică
dacă cea mai mică carte a mâinii este carte 10, iar în caz afirmativ avem o mână de tip Royal
Flush, iar rangul devine 10. În cazul în care avem minim cici căr ți de aceeași culoare
neconsecutive, ave m o mână de tip Flush, iar rangul devine 6. Dacă nu avem minim cinci
cărți de aceeași culoare se va trece la verificarea dac ă avem cinci căr ți consecutive pentru a
obține o mân ă de tip Straight cu rangul 5. La fel ca și la metoda getHand1(), se va returna la
finalul metodei un obiect Hand care va con ține rangul cel mai mare și c ărțile care îl compun.
Metoda ini țială evaluateHand() va compara rangurile celor două obiecte de tip Hand
obținute din metodele getHand1() și getHand2(), și va returna obiectul cu r angul mai mare.
5.2.4 Clasele Card, Deck și gamelogic.table.Table
Clasa Card implementează structura unei căr ți de joc. Ea folsește în constructor întregi
de la 2 la 14 pentru a reprezenta căr țile de la doiar l as , unde 11 este Juvete, 12 Dama, 13
Popa, iar 14 Asul. Pentru culoare se folse ște codare:
1.Roșu
2.Negru
3.Romb
4.Treflă
Tot aici se stabile ște și atribut dealt, pus pe valoarea 1 dac ă cartea a fost deja împăr țită
vreunui jucător pentru a evita situa ția apariției unei c ărți de dou ă ori. Clasa con ține, în rest
doar metode get/set pentru extragerea informa țiilor despre num ăr, culoare sau despre flag -ul
dealt.
Clasa Deck con ține ca și atribut un tablou de obiecte Card de m ărimea 53 pentru cele
52 de căr ți posibile. Aceasta clas ă poate reseta flag -ul cărților înapoi pe 0 pentru a le face
eligibile pentru fi fi din nou împăr țite, în alt ă rundă evident, prin metoda shuffle() . În
constructorul acestei clase se crează obiectele aferente de tip Card a tuturor căr ților posibile și
se rețin în tabloul cards. Cea ma i importantă metodă a acestei clase este metoda deal() care
returnează un obiect Card aleator:
inti=0;
Random randomGenerator = newRandom();
do{
i = randomGenerator.nextInt(52)+1;
}while (cards [i].getDealt()==1);
cards [i].setDealt();
return cards [i];
Algoritmul necesar ob ținerii unei c ărți aleatoare este bazat pe un obiect a clasei Random, care
generează numere întregi aleatore și uniform distribuite pe plaja [2,52]. Astfel se va returna
obiectul card aflat în tabloul cards la poz iția indicat ă de întregul aleator ob ținut. Înainte ca
acest obiect să fie returnat, trebuie setat flag -ul obiectului Card de la indecele respectiv,
pentru a evita reîmpăr țirea aceluiași obiect.
Subpachetul gamelogic.table con ține clasa Table ase mănătoare cași comportament cu
cele două clase prezentate mai sus. Clasa Table con ține ca și atribut o list ă a jucătorilor
înscri și la mas ăși are rolul de a furniza informațiile necesare jocului despre juc ătorii de la

Facultatea de Automatica si Calculatoare U.P.T.
40
masă. Totu și, clasa Table este și cea care lan sează în execu ție și atributul s ău cel mai valoros,
obiectul Game. În momentul apelării metodei startGameThread(Executor exec) se lansează în
execuție firul de execuție Game. Tot în aceast ă clasă, găsim implementată și metoda de
join(TablePlayer)
this.players .add(player);
tableInfo .incrementPlayers();
this.theGame .addWaitingPlayer( new
GamePlayer(player, this.getDefaultChips()));
System. out.println( "added palyer " + player + ":"+tableInfo );
care are rolul de a crea o instan ță GamePlayer care prime ște ca și parametru obiectul
TablePlayer, și care va fi ad ăugat prin metoda addWaitingPlayer(…) listei waitingPlayers a
obiectului Game.
5.3 Pachetul player
Pachetul player con ține trei clase și anume Player, TablePlayer și GamePlayer. Prima
reprezent are utilizatorului, în momentul în care acesta intră în sistem, este ce implementată de
clasa Player. Aceasta oferă func ționalitate relativ llimitat ă, dar va compensa datorită faptului
că un atribut al clasei TablePlayer va fi o instan ță de tip Player. Un obiect TablePlayer este
creat în clasa ce implementează interfa ța la distanț ă RemoteLobby, anume
RemoteLobbyImpl. Aici, obiectul TablePlayer creat va fi tr imis ca și parametru
constructorului clasei RemoteTableImpl, al cărei Stub va fi transmis clientului. Clasa
GamePlayer extinde clasa TablePlayer. Instan ță a acesteia este folosită în clasa Table, în
metoda join(TablePlayer) unde se crează un obiect Gameplayer , care prime ște un obiect
TablePlayer ca și parametru, urmând s ă fie adăugat tabloului de jucător i care reprezintă lista
jucătorilor în a șteptare a atributului Game al clasei Table.
5.4 Pachetul server.rmi
Acest pachet include implementările tuturor interfe țelor la distanț ă ale servicilor
oferite de server. Clasele incluse în acest pachet sunt:
Rem oteLoginImpl, reprezintă clasa care implementează interfa ța la distanț ă
RemoteLogin. Rolul acesteia este de a valida detaliile de autentificare ale utilizatorului
câtși de a exporta obiectul la distanț ă de tip RemoteServer
RemoteServerImpl, reprezintă cla sa care implementează interfa ța la distanț ă
RemoteServer. Func ționalitatea implementat ă de această clasă este exportarea unui
obiect la distan ță de tip RemoteLobby în metoda getLobby() și returnarea acestui Stub
către client. Tot aic itrebuie implementat și serviciul de logout().
RemoteLobbyImpl, reprezintă clasa care implementează interfa ța la distanț ă
RemoteLobby. Aici regăsim serviciile ob ținere a informațiilor utile despre mese cât și
metoda de a șezare la o mas ă anume, metodă care returnează clientului un Stub al
obiectului la distan ță de tip RemoteTable
RemoteTableImpl, clasă care reprezintă implementarea interfe ței la distanț ă
RemoteTable. Rolul acesteia este de a adăuga un utilizator la masa dorită, aleasă în
Lobyy -ul utilizatorului.

Facultatea de Automatica si Calculatoare U.P.T.
41
5.5Comunicare a client -server prin invocarea metodelor la distan ță
Pentru a în țelege mai bine cum funcționeaz ă sistemul de comunicare și de transmitere
a Stub -urilor ca valori returnate ale altor metode invocate la distan ță, putem consulta
diagrama de secven țe din figu ra 10 de mai jos.
Fig.10 Diagramă de secven țe a comunic ării client -server

Facultatea de Automatica si Calculatoare U.P.T.
42
Comunicarea începe pe partea de server în clasa ServerStarter care va crea o instan ță a
clasei RemoteLoginImpl și o va înregistra în registrul RMI, care trebuie s ă fie activ p e portul
standard 1099:
lc = (RemoteLogin)UnicastRemoteObject. exportObject (lc);
Naming. rebind ("rmi://192.168.0.101/RemoteLogin" , lc);
Clasa ClientStarter va căuta prin metoda lookup() al clasei java.rmi.Naming, obiectul la
distanță, utilizând URL -ul sp ecificat
String adress = "rmi://192.168.0.101/RemoteLogin
//Fetching RemoteLogin object
RemoteLogin lc = null;
try{
lc = (RemoteLogin)Naming. lookup (adress);
}catch (MalformedURLException e) {
e.printStackTrace();
}catch (NotBoundExc eption e) {
e.printStackTrace();
}catch (RemoteException e){
e.printStackTrace();
}
După ce clientul a ob ținut obiectul la distanț ă va folosi metoda login(user,pass) a acestuia
pentru a transmite serverului datele de logare și pentru a primi ca valoare returnată Stub-ul
clasei RemoteServerImpl. Clientul va invoca metoda la distan ță getLobby() pentru a primi, ca
obiect returnat, Stub -ul clasei RemoteLobbyImpl. Pe acest Stub, clientul poate invoca metoda
la distanță getTableInfos() pentru a ob ține informațiile necesare alegeri unei mese, adic ă
indicele meselor și num ărul de jucători de la fiecare masă. Invocarea metodei la distan ță
joinTable(..) îl va adăuga liste i de jucători a mesei selectate:
Table joinedTable = this.theLobby .getTable(tableId) ;
RemoteTable tc = newRemoteTableImpl(joinedTable, new
TablePlayer( this.requestor , client));
RemoteTable stub = (RemoteTable)UnicastRemoteObject. exportObject (tc);
return stub;
În momentul în care utilizatorul a fost adăugat la o masă de joc, el v a trebui să a ștepte
începerea unei noi runde de joc sau intrarea unui al doilea jucător la masă. În acest moment,
server -ul va fi cel care apelează metode la distan ță asupra obiectului care implementează
interfața la distanț ă a clientului numită RemoteClie nt. Din acest moment, din punct de vedere
al comunicării RMI, server -ul devine client, iar clientul devine server.
Obiectelele Round, reprezentând etapele unei partide, instan țiate de c ătre firul de
execuție Game al mesei curente, va apela, în momentul în care utilizatorul în cauză trebuie să
acționeze, metodele necesare obțineri acțiuni de joc dorite de c ătre utilizator. Tot în instan țe
ale clasei Round vor fi apelate și metodele la distanț ă ale clientului prin care se transmit
informațiile jocului, neces are reactualizării interfe ței grafice. Metoda promptAction()
menționat ă va returna server -ului acțiunea dorit ă de utilizator.

Facultatea de Automatica si Calculatoare U.P.T.
43
Capitolul 6. Implementarea codului pe partea de client
Pe partea de client a aplica ției g ăsim trei categori de clase și an ume clasa responsabilă
cu pornirea aplica ției-client, care este o clasă ce extinde JApplet, clasa care implementează
interfața la distanț ă a clientului și clasele care controleaz ă interfața grafic ă a utilizatorului.
Clasele ClientFrame și CardPainter, car e controlează și reactualizeaz ă interfața grafic ă
a utilizatorului au fost discutate în capitolul în capitolul 3.3, astfel se va descrie în acest
capitol doar clasa responsabilă cu lansarea aplica ției-client și clasa care implementeaz ă
interfața la distanț ă RemoteClient.
Clasa ClientStarter extinde clasa JApplet și este astfel implementat ă pentru a putea fi
încărcată într -o pagină html într -un browser, la alegere, care suportă Java. Metoda init(),
specifică Applet -urilor con ține urm ătoarele instruc țiuni:
try{
java.awt.EventQueue. invokeAndWait (newRunnable() {
public void run() {
initComponents();
}
});
}catch (Exception ex) {
ex.printStackTrac e();
}
Metoda initComponents() este apelată în interiorul metodei statice invokeAndWait(…) pentru
a fi executată în firul de execu ție Event Dispatch Thread, deoarece acesta este singurul fir de
execuție valid pentru reactualizarea corect ă a interfe țeigrafice, procesând eenimentele venite
din coadă de evenimente AWT. Metoda initComponents() în sine, ini țializeaz ă componentele
grafice ale formularului de autentificare care va fi afi șat in pagina html. După ce utilizatorul
introduce datele sale de înregis trare în sistem va apasa butonul Submit. Metoda care captează
acest eveniment este va apela metoda initiate() care demarează procesul de comunicare între
client și server.
Clasa RemoteClientImpl implementează interfa ța la distanț ă a utilizatorului numită
RemoteClient. Metodele acestui obiect la distan ță sunt apelate de către server pentru a
reactualiza informa țiile utilizatorului și pentru a obține noi informații de la acesta. Metoda
update() a acestei clase are rolul de a înnoi informa țiile despre joc p rimite de la server:
if(s.indexOf( "won" )==-1)
{
players [player]=name;
playerChips [player]=chips;
if(s.indexOf( "folded" )==-1){
inHand [player]=1;
}else {
inHand [player]=0;
}
}
if(s.indexOf( "initiate" )==-1)
{
if(s.index Of("You have:" )==-1)
frame .setTextArea(s);
else frame .setCardInfo(s);
}
if(round >=1)
frame .setTableInfo( round ,this.players ,this.playerChips ,
this.holecards ,this.playerNumber ,flop,turn,river ,inHand );

Facultatea de Automatica si Calculatoare U.P.T.
44
Secvența de cod prezentat ă ilustrează modul în care sunt primite de la server
informații despre fiecare juc ător, privind numele său și num ărul de jetoane pe care îl de ține. În
tabloul inHand se re ține dac ă un anumit jucător a ie șit din mân ă prin setarea flag -ului pe 0. În
cazul în care String -ul primit con ține secvența „initiate”, este vorba de un apel de
reinițializare,semnificând c ă se începe o nouă rundă. În finalul metodei se apelează metoda
setTableInfo(…) al obiectului frame pentru a transmite si JFrame -ului aferent interfe ței grafice
datele primite în legătură cu schimbările la masă.
Metoda giveCards() este apelată la începutul fiecărei partide pentru a transmite
clientului cele două căr ți personale și pentru a inițializa num ărul jucătorului curent printre
indicii tabloului de jucători obținute prin metoda update().
Metoda give Flop() este responsabilă pentru recep ționarea celor primelor trei c ărți
comune. Acestea, ca și în cazul metodei giveCards() sunt transmise obiectului frame în scopul
de a reactualiza interfa ța grafic ă.
Metoda giv eTurn() prime ște de la server ca parametru cea de -a patra carte comună de
joc. Următoare metodă giveRiver() este aproape identică cu cea anterioară, doar că acesta
trimite interfe ței grafice cea de -a cincea carte comună.
Metoda getBet() returnează un într eg obținut din valoarea curent ă a JSlider -ului
interfeței grafice. Aceast ă valoare reprezintă cantitatea de jetoane, din cele personale, pe care
utilizatorul dore ște să le parieze.
Metoda setWinner() transmite interfe ței un întreg,reprezentând num ărul juc ătorului
care a câ știgat runda cât și c ărțile acestuia, cu scopul de a fi afișate în interfața grafic ă.
Metoda promptAction() cuprinde următoarea secven ță de cod:
frame .setSlider( playerChips [playerNumber ]);
frame .showButtons(bet);
while (frame .isBu ttonPressed()== false );
c=frame .getOption();
frame .hideButtons();
if(c==1)
return newEvent( "Fold" );
else if(c==2){
return newEvent( "Call" );
}else if(c==3){
return newEvent( "Raise" );
}else return newEvent( "Problem" );
Prima instrucțiune reprezint ă setarea JSlider -ului interfe ței grafice pe valoarea specificat ă de
numărul de jetoane pe care clientul le posedă la momentul dat. Apelul metodei
frame.showButtons(bet) are rolul de a anun ța interfața grafic ă de necesitatea afi șării
butoanelor de comandă Fold,Check/Call și Bet/Raise, deoarece este rândul juc ătorului curent
să acționeze. Bucla while se va repeta pân ă în momentul în care jucătorul va apăsa unul din
cele trei butoane. În variabila întreagă c vom re ține opțiunea juc ătorul ui, iar interfa ța grafic ă
va fi anun țată să nu mai afi șeze butoanele de comand ă.
Următorul pas îl reprezintă crearea unui nou obiect Event, care va incapsula op țiunea
jucătorului. Acestea sunt hardcodate în interfa ța grafic ă cu valorile întregi 1, 2 și 3 pentru
Fold, Check/Call și respectiv Bet/Raise. Metoda va returna server -ului obiectul Event de unde
acesta își va extrage informația dorit ă.

Facultatea de Automatica si Calculatoare U.P.T.
45
Capitolul 7. Punerea în func țiune și cerințele speciale
Pentru ca aplica ția să poată fi rulată trebuie să ne asigurăm ca pe host -ul server -ului se
regăsește instalat un server HTTP de unde aplicația poate s ă descarce clasele necesare. Pentru
dezvoltarea aplica ției s -a folosit server -ul open -source HTTP Apache 2.2, iar exemplele de
instalare se vor baza pe utiliz area acestui server, dar acest fapt nu împiedică folosirea oricărui
server de acest gen.
Majoritatea serverelor HTTP asigură accesul la directorul public prin utilizarea unui
URL de forma „http://host/username/”. Serverul Apache permite folosirea URL -ului sub
forma „http://ipAddress/ ”. Acest fapt trebuie precizat deoarece codebase -ul applet -ului se va
situa într -un director situat în directorul public.
Dacă nu avem acces la fi șierele compilate ale aplicației le putem compi la din linia de
comandă folosind compilatoarele javac și rmic. În acest caz, trebuie specifica unde se vor
scrie fișierele .class rezultate. Pentru aplicația de faț ă aceste se vor scrie într -un director,
codebase, de exemplu situat în directorul public al serverului. În primul rând, trebuie să ne
asigurăm că directoarele codebase -ului și cel în care se reg ăsesc fi șierele .java sunt vizibile
CLASSPATH -ului local. Pentru a compila fi șierele .java vom folosi, de exemplu , în linia de
comandă:
javac –d /Pathsp reDirectorulPublic/director_codebase numeleÎntregAlPachetului.Fi șier.java
Comanda va crea automat ierarhia de directoare aferente pachetelor și subpachetelor în
directorul ales. După ce ob ține toate fișierele .class aferente aplicației, putem trece la cr earea
Stub-urilorși a Scheleților. Aceștia se vor obține folosind compilatorul rmic asupra claselor
care impementează interfe țe la distanț ă. Compilatorul rmic, care este integrat in Java
Development Kit , recompilează fi șierele .class ale claselor obiectel or la distan țăși va crea în
acela și director dou ă fișiere noi care vvor avea denumirea fișierului .class c ăruia i s -au
adăugat sufixele _Stub și Skel. Folosirea compilatorului rmic este simpl ă:
Rmic –d /caleaSpredirectorulPublic/director_codebase numeleP achetului.Fi șier.class
Opțiunea –d directorul în care vor fi amplasate noile fi șiere .class obținute prin compilare.
Următorul pas este lansarea în execu ție a registrului RMI care implică folosirea folosire
start rmiregistry –pentru sistem de operare Win dows
rmiregistry & pentru Solaris
Prin această comandă a fost porni registrul RMI pe portul standard 1099. Registrul RMI
trebuie oprit și repornit dac ă dorim să aducem modificări vreunei interfe țe la distanț ă. Odată
ce registrul RMI a pornit, putem lansa în execuție serverul. Pentru aceasta, trebuie s ă stabilim
proprietatea de codebase, astfel încât stub -urile să poată descărca dinamic clasele necesare
clientului. Pornire serverului se face atunci astfel:
Java –Djava.rmi.serve.codebase=http://caleCătreDir Public/dir_codebase/ ServerStarter &
Ultimul pas îl reprezintă mutarea paginii html care va încărca applet -ul în directorul public și
introducerea în bara de adrese a unui browser la alegere, care oferă suport Java, a adresei
URL necesare accesării acest uia. Acest pas presupune că în pagina html men ționat ă s-a stabilt
codebase -ul applet -ului cât și fișierul ClientStarter.class ce trebuie înc ărcat.

Facultatea de Automatica si Calculatoare U.P.T.
46
Capitolul 8. Concluzii
Aplicația prezentat ă în această lucrare este destinată jocului de Poker în orice fel de
rețea. Sistemul este preg ătit pentru a fi rulat într -o rețea local ă, cum de altfel a fost și
dezvoltat, dar întrune ște toate cerințele unui sistem client -server, devenind astfel utilizabil pe
internet prin instalarea și configurarea acestuia pe un serv erși accesarea lui prin intermediul
unui browser de pe orice alt calculator.
Avantajul aplica ției const ă însructura sa de aplica ție tip „no download required”, care
face ca aplica ția să fie portabilă pe absolut orice sistem de operare care oferă suport Java.
Există, la ora actuală, aplica ții asem ănătoare de talie mondială cum ar fi Absolute Poker,
Pacific Poker sau Par ty Poker, care înregistrează succese enorme datorită tehnologiei bazate
pe Java folosite. Avantajul clar al acestui tip de sistem îl prez intă faptul ca u nutilizator poate
accesa sistemul de oriunde, nefiind obligat să descarce și să instaleze aplica ția înainte de
rulare și nici nu va conta platforma calculatorului de pe care este accesat, fie aceasta
Windows, Linux sau Mac. Alt avantaj al aplicației il reprezint ă capacitatea de a fi extins.
Direcțiile de dezvoltare au la baz ă implementarea mai multor clien ți bazați pe tehnologi
diferite. Un proiect asemănător, dar mult mai dezvoltat îl reprezintă The CSPoker Project,
care folose ște mai multe tehnologi de comunicare,cum ar fi conexiuni HTTP, conexiune pe
socket -uri transmi țând conținut XML sau tehnologia RMI , câtși mai mulți clienți bazați pe
tehnologi diferite. Aplicația prezentat ă se rezumă la folosirea tehnologiei Remote Method
Invocation pentru comunicare și a rul ării clientului sub forma unui applet integrat într -o
pagină html. Extinderea clientului aplica ției prin tehnologii precum JavaFX sau Adobe Flex
este realizabilă într -o manieră relativ simplă dacă se posedă cuno științele necesare .Aplicația
are o structură și o implementare preg ătită pentru adăugarea unei baze de date care să con țină
datele importante despre utilizatori, cum ar fi numele, parola, numărul de jetoane acumulat
sau posibile preferin țe presetate în sistem. Tehnologia d e comunicare ar putea fi schimbată cu
o tehnologie mai universală precum CORBA, dar cum în momentul de fa ță clientul este scris
doar în Java, această variantă nu a fost necesară, deoarece portabilitatea sistemului se extinde
pe aproape orice platformă.
Dezavantajele aplica ției sunt evidențiate de limit ările sale actuale. Încă există situa ții
de joc care nu au fost tratate și implementate corespunz ător. Există două astfel de scenarii.Un
exemplu ar fi scenariul în care doi sau mai mul ți juc ători ar de ține ac eeși mân ă de joc. În
termen ide Texas Hold’em aceasta situa ție se numește „a split -pot” și presupune împ ărțirea
corectă a jetoanelor între jucători în func ție de cantitatea de jetoane depuse în pot. Cel ălalt
exemplu este scenariul în care doi sau mai mul țijucător, care au cantită ți diferite de jetoane,
pariază toate jetoanele pe care le posedă. În acel moment sistemul ar trebui să stabilească pot –
uri deferite pentru jucători pentru a rămâne corect fa ță de discrepan ța de jetoane dintre ei.
Totu și aceste det alii sunt relativ simplu de integrat, mic șorarea influenței negative pe care
acestea o au auspra jocului devenind facilă. Restul scenariilor de joc au fost testate exhaustiv
iar rata de succes al acestora a fost cel pu țin satisf ăcătoare. S -a încercat rular ea sistemului în
condiții limit ă cum ar fi pe conexiuni slabe sau printr -un număr mare de clien ți care acceseaz ă
simultan sistemul. Rezultatele ob ținute au fost deasemenea cel puțin satisf ăcatoare.
Evaluatorul de mâini de ține o rat ă de succes de 96% care e ste suficientă pentru un asemena
proiect.
Deși prin cautarea pe orice search engine de pe Internet se g ăsesc o multitudine de
asemenea aplica ții, bazate pe aceleași tehnologi sau pe tehnologii asem ănătoare, simplitatea
structurii și codul implementat , of eră posibilitatea de a extinde aplica ția.Există deja por țiuni
ale aplica ției care trebuie doar implementate pentru a extinde funcționalitatea aplicației într -un
anumit mod.

Facultatea de Automatica si Calculatoare U.P.T.
47
Bibliografie
[Hgi97] Gilbert, H. (1997, Jan 10). Java. Preluat de pe
http://pclt.cis.yale.edu/pclt/WEBAPP/java.htm
[Wil01] Grosso, W. (2001). Java RMI, Ed. O’Reilly
[Ioa01] Jurca, I. (2001). Programarea re țelelor de calculatoare . Editura de
Vest
[Jur06 ] Jurca, I. (2006). Bazele programării orientate pe obiecte. Editura de
Vest
[Chr99] Lambert, C (1 iulie 1999). RMI: Pure Java Distributed Computing.
www.//java.sys -con.com/node/36508
[Mal03] Maly, R. J. (martie 2003). Comparison of Centralized and
Decenterlized Networking . Zurich
[Ora10] Oracle Corporation. (2010). Remote Method Invocation.
http://java.sun.com/developer/onlineTr aining/rmi/RMI.html
[Obe01] Oberg, R. (2001). Mastering RMI. Ed. John Wiley & Sons, Inc.
[Rub10] Rubin, J. & Watson, I. (2010) Computer Poker: A Review.
Auckland: Department of Computer Science, University of Auckland, New
Zealand.
[Sun06] Sun Microsys tems Inc. (2006). javase. www.java.sun.com
[Sun10] Sun Microsystems Inc. (2010) Whitepaper.
http://java.sun.com/javase/technolog ies/core/basic/rmi/whitepaper/index.jsp
[Ven] Venkat Intelligroup Inc. (a.n.). Building Distributed Applications using
Java RMI.
http://www.uniforum.chi.il.us/slides/javarmi/ppframe .htm
[1] http://thor.info.uaic.ro/~acf/java/slides/swing_slide.pdf

Facultatea de Automatica si Calculatoare U.P.T.
48

Facultatea de Automatica si Calculatoare U.P.T.
49

Facultatea de Automatica si Calculatoare U.P.T.
50

Facultatea de Automatica si Calculatoare U.P.T.
51

Similar Posts