Sunteți pe pagina 1din 64

SO2 - Comunicatii si SO distribuite

COMUNICAII NTRE SISTEME DE OPERARE I SO DISTRIBUITE..........................2


3.1

ADRESRI N INTERNET ..........................................................................................................2


3.1.1
Adrese IP i clase de adrese ...........................................................................2
3.1.2
Adrese Internet; servere de domenii .................................................................................5

ELEMENTE DE LIMBAJ HTML ............................................................................................13

4.1
4.2
4.3

INTRODUCERE ................................................................................................................13
UN EXEMPLU SIMPLU DE FIIER HTML.............................................................14
STRUCTURA UNUI DOCUMENT HTML ...............................................................16

4.3.1
4.3.2
4.3.3
4.3.4

Antet, fond i culori .........................................................................................................16


Marcaje de formatare a documentului ...........................................................................18
Specificare tip i format caractere..................................................................................20
Scrierea caracterelor ne-standard..................................................................................21
4.4
LEGTURI HIPERTEXT ................................................................................................22
4.5
LISTE I TABELE ....................................................................................................................23
4.5.1
Marcaje de tip list..........................................................................................................23
4.5.2
Tabele ..............................................................................................................................26
4.6
INTRODUCEREA DE IMAGINI ....................................................................................28
5

INTERACIUNI HTML ............................................................................................................30

5.1

FORMULARE HTML ...................................................................................................30


5.1.1
Principiul de funcionare ................................................................................................30
5.1.2
Un exemplu simplu de formular......................................................................................31
5.1.3
Principalele taguri folosite la formulare HTML ............................................................33
5.2
CGI I COMUNICAII PRIN URLCONNECTION ......................................................................35
5.2.1
Tehnologia CGI ...............................................................................................................35
5.3
CONSTRUCIA UNUI CONTOR DE PAGINI WEB ......................................................................35
5.3.1
Iniializarea fiierului contor ..........................................................................................36
5.3.2
Programul CGI................................................................................................................36
6

SOCKET: UTILIZARE DIN C SUB UNIX I DIN C++ SUB WINDOWS ........................37
6.1
6.2

NOIUNEA DE SOCKET ..........................................................................................................37


TIPURI DE SOCKET .................................................................................................................37
Socket stream .............................................................................................................................................37
Socket datagram.........................................................................................................................................38
Repere pentru alegerea tipului de socket...................................................................................................38

6.3
MECANISMUL DE SOCKET N LIMBAJUL C.............................................................................38
6.3.1
Adrese socket ...................................................................................................................39
6.4
SCHEME CADRU DE IMPLEMENTRI CLIENT / SERVER ..........................................................40
6.4.1
Scenariul aplicaiilor socket stream ...............................................................................40
6.4.2
Scenariul aplicaiilor socket datagram...........................................................................42
6.5
BIBLIOTECA DE APELURI SISTEM SOCKET .............................................................................43
6.5.1
Apeluri socket de conexiune............................................................................................43
Sintaxele apelurilor: socket, bind, listen, connect, accept.........................................................................43
Apelul sistem socket ..................................................................................................................................44
Apelul sistem bind .....................................................................................................................................44
Apelul sistem listen....................................................................................................................................44
Apelul sistem connect................................................................................................................................44
Apelul sistem accept ..................................................................................................................................45

6.5.2
6.5.3

Particulariti socket Windows .......................................................................................45


Operaii de I/O prin socket..............................................................................................46

Apelurile sistem send, recv, sendto, recvfrom ..........................................................................................46


Comparaii cu apelurile read i write.........................................................................................................46
Apelurile sistem sendmsg i recvmsg........................................................................................................47
Rutine de conversii ale octeilor i ntregilor ...........................................................................................47
Rutine de manevrare a irurilor de octei ..................................................................................................48

6.5.4

Gestiunea adreselor IP i Internet ..................................................................................48

Rutinele inet_addr i inet_ntoa .................................................................................................................48


Rutinele gethostname i gethostbyname ...................................................................................................49

6.6
EXEMPLE DE APLICAII CLIENT / SERVER CU SOCKET ..........................................................49
6.6.1
rdir: Rezumat de director la distan..............................................................................49

SO2 - Comunicatii si SO distribuite

Prezentarea problemei................................................................................................................................49
O variant rdir prin TCP ............................................................................................................................50

6.6.2

Client FTP noninteractiv.................................................................................................53

Aplicatia Client FTP.cpp........................................................................................................................54

3 Comunicaii ntre sisteme de operare i SO distribuite


3.1 Adresri n Internet
3.1.1 Adrese IP i clase de adrese
O adres IP, folosit de ctre pachetul TCP/IP, este un numr ntreg i pozitiv, reprezentat pe 32 de
bii. Deci exist maximum 232 astfel de adrese.
Structura unei adrese IP; clase
Structura general a unei astfel de adrese este dat n fig. 1.18.
Clasa
Bii de identificare a
adresei reelei n cadrul Internet
Clasa

Bii de identificare a
hostului n cadrul reelei
locale

Reea

Host
Bii de
subreea

Bii de host
n subreea

Figura 3.1 Structura unei adrese IP


Din cei 32 de bii, numrul de bii afectai fiecrui cmp din adres depinde de clasa adresei. n
prezent exist 3 clase de adrese: clasa A, clasa B i clasa C, prezentate n figurile 1.19, 1.20 i 1.21.
Deocamdat nefolosit, este rezervat i o a patra, clasa D.
Reea

Host

0
7 bii

24 bii

Figura 3.2 Structura adresei de clas A

Reea

Host

1 0
14 bii

16 bii

Figura 3.3 Structura unei adrese de clas B

SO2 - Comunicatii si SO distribuite

Reea

Host

21 bii

8 bii

1 1 0

Figura 3.4 Structura unei adrese de clas C


Adresele de clas D ncep cu irul de patru bii 1110, restul de 28 de bii fiind rezervai.
Se poate uor vedea c exist un numr finit de adrese posibile din fiecare clas i un numr finit de
hosturi n cadrul fiecrei reele. Dac se face abstracie de un numr, de altfel foarte mic, de
configuraii de bii care sunt rezervate n scopuri administrative, limitele maxime de adresare
posibile sunt:
Clasa A, maximum 27 reele a cte maximum 224 -1 hosturi fiecare;
Clasa B, maximum 214 reele a cte maximum 216 -1 hosturi fiecare;
Clasa C, maximum 221 reele a cte maximum 28 -1 hosturi fiecare.
Aceste limitri au nceput ns s amenine funcionarea rezonabil a comunitii Internet. n [34] se
arat ns c se intreprind cercetri de extindere a adreselor IP la 48 de bii sau chiar la mai mult, cu
modificarea i proliferarea unei noi versiuni de TCP/IP numit IPV6. Aceast extindere este
necesar att datorit creterii exponeniale a numrului de hosturi care se conecteaz la Internet,
ct i datorit tendinelor de includere n Internet a comunicaiilor clasice mass-media: TV, radio,
telefonie etc.
Noi ne rezumm la prezentarea adreselor actuale. Consoriul NIC atribuie numai clasa de adres i
cmpul Reea, lsnd dispoziia administratorilor reelei s gestioneze cmpul Host i eventual
partajarea acestuia n subcmpul de subreea i cel de host n subreea, aa cum sunt ele
ilustrate n fig. 1.18.
Atribuirea unei anumite clase de adres se face n funcie de dimensiunea acesteia, aa cum s-a
artat mai sus. n consecin, adresele de clas A sunt atribuite numai reelelor speciale, de
dimensiuni foarte mari. Aceste adrese au fost atribuite mai ales la primele reele conectate la
Internet. n prezent aceste adrese sunt atribuite foarte greu.
Adresele de clas B sunt rezervate reelelor de dimensiuni relativ mari, cu relativ multe hosturi n
ele.
Majoritatea adreselor atribuite n prezent sunt cele de clas C. n situaia n care o adres de clas C
nu este suficient, sunt atribuite mai multe adrese de acest tip.
Reprezentarea intern a unei adrese IP este un ir de 32 de bii, plasai n patru octei consecutivi.
Reprezentarea extern a unei astfel de adrese se face prin 4 numere ntregi separate prin trei puncte.
Fiecare numr indic, n ordine, valoarile celor patru octei (deci nu valorile cmpurilor adresei!).
Iat cteva exemple:
S considerm adresa de clas A: 0 1111101 000011010100100100001111. Grupm
n cte 8 bii i convertim fiecare ntreg binar de 8 bii ntr-un numr n baza 10. Se obine
reprezentarea extern: 125.13.73.15.
Analog, adresa de clas B: 10 10111111011100
reprezentarea extern: 175.220.14.238.

0000111011101110 se scrie n

SO2 - Comunicatii si SO distribuite

n fine, adresa de clas C: 110 000011110001000101000 00100001 se scrie n


reprezentarea extern: 193.226.40.33.
Din exemplele de mai sus se poate desprinde uor regula dup care se poate identifica, din scrierea
extern, clasa de adres. Dac primul numr este ntre 0 i 127, atunci este vorba de o adres de
clas A. Dac primul numr este ntre 128 i 191 atunci este vorba de o adres de clas B. Clasa C
are primul numr ntre 192 i 223, iar clasa D ntre 224 i 255.
Subreele i mti de reea
Schema de adresare Internet, proiectat pentru sute de reele, nu a anticipat proliferarea reelelor
LAN. Drept consecin, o prim problem: trebuie, n mod normal, s se atribuie cte o adres IP la
fiecare staie dintr-o reea LAN. Aceasta impune existena unor tabele de rutare foarte mari i de
aici un efort imens de a ntreine aceste adrese. Evitarea acestei situaii se face folosind conceptul de
subreea, prin intermediul cruia rutarea este distribuit pe mai multe servere, fiecare gestionnd un
numr mai mic de adrese.
Mecanismul de subreele divide zona Host n dou subzone: subzona de subreea i subzona de
host n subreea. Primii bii ai zonei, ntr-un numr impus de necesiti, sunt rezervai
subreelei, iar ultimii pentru hostul n cadrul subreelei. Nu este obligatoriu ca subzonele s fie
constituite din secvene contigue de bii; este de exemplu posibil ca biii de rang par s desemneze
subreea, iar cei de rang impar s desemneze host. Este, ns indicat ca fiecare subzon s fie
specificat printr-o succesiune de bii consecutivi.
De exemplu, la adresa de clas C 193.231.18.XXX, sunt administrate patru reele LAN, avnd
fiecare n jur de 36-40 staii fiecare. n aceast situaie, administratorul decide definirea a patru
subreele. n consecin, el decide ca primii doi bii s desemneze una dintre cele patru subreele, iar
restul de ase bii desemneaz hosturile din cadrul subreelei. Lsm pe seama cititorului s
(descompun n reprezentare intern pe bii i s) constate c urmtoarele patru adrese sunt situate
n patru subreele diferite: 193.231.18.34, 193.231.18.66, 193.231.18.129,
193.231.18.193.
Pentru a putea separa cele dou zone se definete conceptul de masc de subreea. Aceasta se
construiete punnd biii corespunztori cmpului clasa, reea i subreea la valoarea 1, iar
cei ai cmpului host la valoarea 0. Pentru exemplul prezentat mai sus, masca de subreea este, n
scriere extern, 255.255.255.192.
Aceste mti sunt utilizate pentru a manevra adresele IP folosind operaiile booleene cunoscute: i
bit cu bit, sau bit cu bit, sau-exclusiv bit cu bit, pentru a izola subreelele sau hosturile n cadrul
subreelelor.
Adrese speciale
Intre adresele IP, cteva sunt rezervate pentru destinaii speciale. Prezentm cteva dintre acestea.

SO2 - Comunicatii si SO distribuite

Adresa 127.0.0.1 este rezervat pentru a desemna, pe orice host, hostul nsui. Fiecare host
folosete aceast adres pentru ai trimite siei pachete de date, testndu-se astfel corecta
funcionare a ierarhiei de protocoale de pe maina local.
Adrese de broadcast Dac ntr-un cmp de adres toi biii au valoarea 1, atunci adresa desemneaz
calculatoarele host din toate subreelele conectate n mod direct la acea adres. Deci o emisie la
aceast adres va fi o emisie spre toate aceste hosturi. Spre exemplu, o astfel de emisie este folosit
de ctre protocolul ARP.
Dac toi biii din cmpul de adres host sunt 0, atunci datele sunt transmise ctre toate hosturile din
subreeaua specificat. Astfel, de exemplu o cerere lansat de ctre adresa 193.226.62.0 este
transmis la toate adresele 193.226.62.n cu n ntre 1 i 254, chiar dac acestea nu sunt
adrese reale.
Corespondena adrese IP - hosturi
Ultima chestiune care trebuie lmurit n legtur cu adresele IP este legat de modul n care se pun
n coresponden adresele IP cu hosturile. n marea majoritate a cazurilor, unui host conectat la
Internet i corespunde o singur adres IP. Exist ns posibilitatea ca unui host s-i corespund mai
multe adrese IP. Aceste hosturi sunt deci accesibile prin mai multe ci.
Regula dup care se face aceast coresponden este urmtoarea: unui host i se atribuie attea
adrese IP cte interfee de reea (plci de reea) are nglobate n el. Mai mult chiar, unei plci de
reea (adaptor de reea) i se pot atribui mai multe interfee logice (o interfa de reea poate fi
configurat cu mai multe adrese IP).
Deci hosturile care sunt noduri de reea, hosturile din care se ramific mai multe tronsoane de reea
etc. au atribuite mai multe adrese IP.
Legtura dintre adresa IP i host este realizat de ctre protocoalele ARP - RARP, prezentate n
1.4.2. Prin acestea se pune n coresponden adresa fizic a interfeei de reea (adres Ethernet,
Token-Ring etc.) cu adresa IP care va fi folosit pentru comunicaii prin protocolul TCP/IP.

3.1.2 Adrese Internet; servere de domenii


Sistemul de adresare Internet - sau cum mai este el numit specificarea de subdomenii, este conceput
nct s permit utilizatorului o scriere mai comod, mai sugestiv i mai elastic a adresei
hosturilor dect cea cu adrese IP. Corespondena ntre specificarea de subdomenii i adresele IP
revine protocolului de aplicaie DNS (Domain Name Service).
Sistemul de adresare n Internet
Analog sistemului de adresare potal, o adresa Internet are o structur relativ fix: Astfel, spre
exemplu, adresa autorului (una dintre ele) este:
florin@cs.ubbcluj.ro

SO2 - Comunicatii si SO distribuite

n traducere, aceasta nseamn c este vorba de utilizatorul cu numele de user florin, care este
membru al domeniului cs (Computer Science) din cadrul subdomeniului ubbcluj (Universitatea
Babes-Bolyai, Cluj), din cadrul subdomeniului ro indicnd ara, Romnia.
Un alt exemplu: una dintre mainile care a fost folosit la testarea programelor din aceast carte are
adresa IP 193.226.40.133, iar adresa ei internet este:
rave.scs.ubbcluj.ro
care nseamn maina cu numele rave, conectat la reeaua subdomeniului scs (Students of
Computer Science) din subdomeniul ubbcluj al domeniului ro.
Se poate constata c exist o analogie cu sistemul potal de adresare. Si n acesta se specific, cu
scopul localizrii: numele i prenumele, strada, numrul, oraul sau satul, eventual codul potal,
judeul, ara.
La adresarea potal fiecare entitate de adres este prefixat de tipul ei: cuvntul strada sau str.
urmat de numele efectiv al strzii, Jud. urmat de numele judeului etc. n consecin, ordinea
entitilor nu este impus. n schimb, la adresarea Internet, ordinea cuvintelor n specificare este
esenial, tipul entitii fiind impus i de poziia cuvntului n specificare.
O adres Internet are una dintre urmtoarele trei forme:
1.

numeuser@domeniu1.domeniu2. .domeniun

2.

numeuser@numehost.domeniu1.domeniu2. .domeniun

3.

numehost.domeniu1.domeniu2. .domeniun

ntre cuvintele i separatorii care compun adresa nu trebuie s apar spaii. Principalul separator
ntre cuvinte este caracterul . (punct).
numeuser indic numele utilizatorului de pe maina numehost (tipul 2 de adres) sau din
domeniu1 (domeniu potal la tipul 1 de adres). numeuser se scrie naintea caracterului
@.Primele dou tipuri de adrese sunt echivalente, n sensul c numehost poate nlocui
domeniile pe care le gestioneaz el. Aceste dou tipuri de adrese sunt folosite n principal la
comunicaiile prin pota electronic sau n discuiile interactive (talk) [20,32]. Mai multe despre
pota electronic, ntr-un capitol urmtor al acestei lucrri, sau n lucrrile [35,20,32]. Adresele de
forma a treia sunt folosite pentru a indica hosturi, i acestea vor fi cele mai utilizate adrese n
lucrarea de fa.
Succesiunea domeniu1.domeniu2. .domeniun indic nivele de organizare, care sunt din
ce n ce mai generale, de la stnga spre dreapta. Astfel, spre exemplu, adresa de host:
rave.scs.ubbcluj.ro
reprezint includerea de nivele din fig. 1.22

SO2 - Comunicatii si SO distribuite

rave

scs

ubbcluj

ro

Internet
Figura 3.5 Un exemplu de includere de domenii
Fiecare nivel de organizare este indicat printr-un nume de domeniu (de fapt nume de subdomeniu),
care este cuprins (inclus) n domeniul scris n dreapta lui.
De aici se deduce prima regul de organizare: fiecare domeniu i definete propriile subdomenii, le
administreaz i le face publice. Deci stabilirea subdomeniilor este strict de competena
administratorului de domeniu.
De exemplu, reeaua de calculatoare a Universitii Babe-Bolyai Cluj, denumit pe scurt
UBBNET, este subreea n cadrul reelei ROEDUNET (Romanian Educational Network).
Administratorii ei, de comun acord cu administratorii domeniului ro, au decis ca numele de
subdomeniu s fie ubbcluj.
La rndul lor, administratorii ubbcluj au decis ca fiecare dintre subdomeniile lui s desemneze o
facultate, un serviciu sau dup caz un departament, n funcie de dimensiunea subreelei parte din
UBBNET pe care o dein. Tot ca un criteriu de fixare de subdomeniu s-a luat n considerare i
amplasarea topografic n municipiul Cluj a diverselor cldiri ale Universitii. La rndul lor, acolo
unde este cazul, subdomeniile de faculti se pot subdivide .a.m.d. n tabelul de mai jos este dat
lista complet a subdomeniilor domeniului ubbcluj la aceast or (septembrie 2002). Numele lor au
fost atribuite, pe ct posibil, n urma unor prescurtri din limba englez.
Bioge
Biolog
Chem
Cs
Econ
Euro
Gct
Geografie
Hiphi
Law
Lett
Math
Stud.math
Ot

Facultatea de Biologie Geologie


Departamentul de Biologie animal
Facultatea de Chimie
Departamentul de Informatic al Facultii de Matematic i
Informatic
Facultatea de Stiine Economice
Facultatea de Studii Europene
Facultatea de Teologie Greco - Catolic
Facultatea de Geografie
Facultatea de Istorie - Filosofie
Facultatea de Drept
Facultatea de Litere
Facultatea de Matematic i Informatic
Studenii matematicieni ai Facultii de Matematic i
Informatic
Facultatea de Teologie Ortodox

SO2 - Comunicatii si SO distribuite

Phys
Polito
Psiedu
Rt
Rct
Scs
Sport
Staff
Tbs

Facultatea de Fizic
Facultatea de Stiine Politice
Facultatea de Psihologie i Stiina Educaiei
Facultatea de Teologie Reformat
Facultatea de Teologie Romano Catolic
Studenii informaticieni ai Facultii de Matematic i
Informatic
Facultatea de Educaie Fizic i Sport
Rectoratul Universitii Babes-Bolyai
Scoala de Bussines Transilvania

Din modul de atribuire a numelor de subdomenii rezult o a doua regul: numrul total de domenii
(n) nu este fixat apriori ci depinde numai de sistemul de organizare adoptat. (Analog cu sistemul
potal clasic, unde o adres ntr-un ora are mai multe elemente dect o adres dintr-un sat mic).
Cel mai general domeniu, cel care se scrie cel mai n dreapta, este un cod care depinde de ar.
Pentru SUA, acesta este codul care indic un domeniu organizaional, unul dintre cele apte din
tabelul de mai jos.
com
edu
gov
int
mil
net
org

Organizaii comerciale
Instituii academice i educaionale
Instituii guvernamentale
Instituii internaionale (NATO, ONU etc)
Instituii militare SUA
Resurse din reeaua Internet
Organizaii non profit

Dac domeniul este nafara SUA, atunci el este un cod care indic ara de apartenen. De obicei,
acesta este din dou litere i coincide cu codul internaional de marcare a autoturismelor. n tabelul
de mai jos indicm 20 dintre aceste coduri.
at
au
ca
ch
de
dk
fi
fr
hu
il

Austria
Australia
Canada
Elveia
Germania
Danemarca
Finlanda
Frana
Ungaria
Israel

it
jp
mx
nz
pl
ro
ru
tr
uk
va

Italia
Japonia
Mexic
Noua Zeeland
Polonia
Romnia
Federaia Rus
Turcia
Marea Britanie
Vatican

Specificrile de domenii pot fi privite ca i structuri arborescente. Da fapt, avem de-a face cu mai
multe structuri arborescente, fiecare dintre ele avnd ca i rdcin numele de domeniu al rii sau,
n cazul SUA, numele domeniului organizaional. n figura 1.23 ilustrm un fragment din domeniul
ro i unul din domeniul fi. La acestea ne vom mai referi i n seciunile urmtoare.

SO2 - Comunicatii si SO distribuite

9
fi

ro
ici

pub
cs

ubbcluj
econ

utcluj

funet

staff
nic

fes

Figura 3.6 Poriuni din arborii domeniilor ro i fi


Acum este momentul s enunm o a treia regul de specificare. Ea se enun simplu: ntr-o
comunicaie surs - destinaie, sursa este obligat s specifice subdomeniile, ncepnd de la cel mai
interior i pn la primul subdomeniu care are ca i subordonat destinaia. Deci, spre exemplu,
pentru o comuncaie ntre mainile nessie.cs.ubbcluj.ro i hercule.utcluj.ro,
trebuie s se specifice doar nessie.cs.ubbcluj i hercule.utcluj. deoarece domeniul
ro le conine pe amndou. (Aa cum, ntr-o scrisoare loco, nu se specific dect strada i numrul,
nu i oraul, judeul etc.).
Mecanismul serverelor de nume (DNS)
Mecanismul serverelor de nume, mai cunoscut sub numele de mecanismul DNS (Domain Name
Service), realizeaz ntr-o manier distribuit, corespondena dintre adresele IP i adresele Internet.
Regula de atribuire stabilete c fiecrei adrese Internet a unui host (tipul 3 din 1.5.3) i corespunde
o unic adres IP. Este ns posibil ca mai multe adrese Internet s aib ca i corespondent o aceeai
adres IP. n acest caz spunem c avem de-a face cu sinonime ale aceleiai maini. De exemplu,
adresele zeus.ubbcluj.ro, ftp.ubbcluj.ro i www.ubbcluj.ro corespund la aceeai
adres IP: 193.231.20.1. Primul nume este numele propriu-zis al mainii, al doilea este
numele serverului FTP, iar al treilea este numele serverului de Web, ultimele dou servere fiind
gzduite tot pe maina zeus.
Mecanismul DNS presupune c reeaua Internet este mpnzit de calculatoare speciale, numite
servere de nume, prescurtat NS (Name Server). Fiecare NS conine dou tipuri de informaii:
1) tabele de coresponden ntre adresele Internet i adresele IP ale unui grup de hosturi aflate n
vecintatea lui;
2) adresele IP i Internet ale ctorva NS vecine lui.
Fiecare domeniu trebuie s aib desemnat cel puin un NS care s-i asigure corespondena adres IP
- adres Internet pentru subdomeniile proprii. Este posibil, dac domeniul este mare, ca aceste
corespondene s fie distribuite pe mai multe NS ale domeniului respectiv.
Cum acioneaz un NS, atunci cnd primete o adres Internet i i se cere adresa IP
corespunztoare? Conform urmtoarelor reguli, aplicate succesiv:

SO2 - Comunicatii si SO distribuite

10

a) Dac adresa Internet se afl n tabelele NS respectiv, atunci ntoarce adresa IP celui care a
solicitat-o. Dac nu, atunci:
b) Dac un domeniu superior din adresa Internet se afl n tabelele NS respectiv, atunci transmite
cererea la NS-ul domeniului superior respectiv. Dac nu, atunci:
c) Dac adresa Internet primit indic un host aflat n acelai domeniu cu NS respectiv, atunci
trimite cererea la NS-ul subdomeniului n care se afl hostul. Dac nu, atunci:
d) Trimite cererea primului NS pe care-l are nregistrat ca NS vecin. Dac acesta nu rezolv cererea,
atunci trimite la urmtorulNS vecin .a.m.d.
e) Dac nici unul dintre NS-urile la care s-a trimis cererea nu ntoarce o adres IP, atunci adresa
Internet este incorect.
Credem c este momentul s dm un exemplu. n fig. 1.23 sunt indicate dou hosturi. S
presupunem c un utilizator de pe maina fes.econ.ubbcluj.ro dorete s solicite un
transfer de fiiere prin FTP de la maina nic.funet.fi. Pentru aceasta, el va da comanda:
...>ftp

nic.funet.fi

Dup cum am artat n 1.4.2, n pachetele IP trebuie s apar adresele IP ale corespondenilor.
Evident, adresa IP a mainii fes.econ.ubbcluj.ro este cunoscut. Pentru a afla adresa IP a
mainii nic.funet.fi se vor parcurge urmtoarele 9 etape:
1. fes.econ.ubbcluj.ro nu gsete n tabelele sale adresa nic.funet.fi, deci nu poate
aplica regula a. Nu gsete nici adresa funet.fi, nici fi, deci nu poate aplica regula b. De
asemenea, nu poate aplica nici regula c, deoarece cele dou hosturi se afl n domenii diferite. n
consecin, aplic regula d i cere NS-ului econ.ubbcluj.ro, care-i este NS vecin, s-i rezolve
cererea.
2. econ.ubbcluj.ro, conform unui raionament analog punctului 1, aplic regula d i cere lui
zeus.ubbcluj.ro, care-i este NS vecin, s-i rezolve cererea.
3. zeus.ubbcluj.ro, conform unui raionament analog punctului 1, aplic regula d i cere lui
hercule.utcluj.ro, care-i este NS vecin, s-i rezolve cererea.
4. hercule.utcluj.ro, conform unui raionament analog punctului 1, aplic regula d i cere
lui pub.pub.ro, care-i este NS vecin, s-i rezolve cererea.
5. pub.pub.ro, conform unui raionament analog punctului 1, aplic regula d i cere lui
ns.ici.ro, care-i este NS vecin, s-i rezolve cererea.
6. ns.ici.ro, conform unui raionament analog punctului 1, aplic regula d i cere lui nsa.rnc.ro, care-i este NS vecin, s-i rezolve cererea.
7. ns-a.rnc.ro are n tabelele sale domeniul fi. Aplic deci regula b i cere la NS-ul
domeniului fi s-i rezolve cererea. Aceast operaiune este ilustrat n fig. 1.21 printr-o linie
punctat care leag ro cu fi.
8. NS-ul domeniului fi, n conformitate cu regula c, cere la NS-ul domeniului funet.fi s-i
rezolve cererea.

SO2 - Comunicatii si SO distribuite

11

9. NS-ul domeniului funet.fi are n tabelele sale adresa IP a mainii nic.funet.fi. n consecin,
conform regulii a, gsete i returneaz adresa IP a mainii. Urmeaz:
10. Adresa IP astfel determinat urmeaz traseul invers rspunznd pozitiv pe rnd NS-urilor
indicate la punctele 9, 8, ..., 3, 2 i n final acesta din urm d rspunsul mainii solicitante. n acest
moment maina fes.econ.ubbcluj.ro dispune de adresa IP a mainii nic.funet.fi.
Cu cele dou adrese, se pot pregti pachetele IP care vor circula ntre cele dou maini (sgeata
dubl ntre fes i nic din fig. 1.23).
Trebuie reinut faptul c rutele de obinere a adreselor IP au ca intermediari numai servere de nume.
n schimb, pachetele IP obinuite au alte trasee. Iat dou astfel de rute ntre aceleai dou hosturi.
Urmele rutelor au fost obinute cu ajutorul comenzii:
...> traceroute

nic.funet.fi

lansat de pe o main din domeniul ubbcluj.ro. Iat primul traseu, realizat prin furnizorul de
servicii Internet RoEduNet, n care se indic adresele Internet i adresele IP ale celor 18 noduri de
pe traseu.
1 UBB-GW.Cluj.Roedu.Net (193.231.20.3)
2 r-bb1-s9-0.Bucharest.roedu.net (192.129.4.201)
3 bucharest-br1-fe6-0-0.rdsnet.ro (193.231.191.33)
4 193.231.184.158 (193.231.184.158)
5 atvie102-tc-s5-2.ebone.net (195.158.245.85)
6 atvie203-tc-r3-0.ebone.net (213.174.68.98)
7 r1-Se0-3-0.0.Wie-VIX.AT.KPNQwest.net (134.222.249.37)
8 r2-PO1-0-0.wie-KQE.AT.kpnqwest.net (134.222.224.53)
9 r1-Se1-1-3.ffm-KQ1.DE.kpnqwest.net (134.222.231.57)
10 r1-Se0-3-0.0.hmbg-KQ1.DE.kpnqwest.net (134.222.230.110)
11 r2-Se1-1-0-0.Sthm-KQ1.SE.KPNQwest.net (134.222.230.150)
12 r4-Se7-0-0-0.Sthm-KQ1.SE.KPNQwest.net (134.222.119.246)
13 s-gw.nordu.net (134.222.119.241)
14 fi-gw.nordu.net (193.10.68.42)
15 funet1-rtr.nordu.net (193.10.252.50)
16 funet6-p13-csc0.funet.fi (193.166.255.209)
17 info1-p40-funet6.funet.fi (193.166.255.110)
nic.funet.fi (193.166.3.1)
A dou rut am obinut-o pornind tot de la o main din domeniul ubbcluj.ro, dar traseul este
realizat print-un furnizor de servicii Internet privat, care ofer o linie de rezerv reelei UBBNet.
Iat cum arat cel de-al doilea traseu.
1
2
3
4

fiber-gw.cluj.astralnet.ro (193.230.247.193)
atv.codec.ro (193.230.240.22)
r0-fe01.cluj.astralnet.ro (193.230.240.98)
atvie103-ta-s6-0-9c0.ebone.net (195.158.245.81)

SO2 - Comunicatii si SO distribuite

12

5 atvie203-tc-r3-0.ebone.net (213.174.68.98)
6 r1-Se0-3-0.0.Wie-VIX.AT.KPNQwest.net (134.222.249.37)
7 r2-PO1-0-0.wie-KQE.AT.kpnqwest.net (134.222.224.53)
8 r1-Se1-1-3.ffm-KQ1.DE.kpnqwest.net (134.222.231.57)
9 r1-Se0-3-0.0.hmbg-KQ1.DE.kpnqwest.net (134.222.230.110)
10 r2-Se1-1-0-0.Sthm-KQ1.SE.KPNQwest.net (134.222.230.150)
11 r4-Se7-0-0-0.Sthm-KQ1.SE.KPNQwest.net (134.222.119.246)
12 s-gw.nordu.net (134.222.119.241)
13 fi-gw.nordu.net (193.10.68.42)
14 funet1-rtr.nordu.net (193.10.252.50)
15 funet6-p13-csc0.funet.fi (193.166.255.209)
16 info1-p40-funet6.funet.fi (193.166.255.110)
17 nic.funet.fi (193.166.3.1)
n ncheierea acestei seciuni, trebuie s artm c un mecanism eficient DNS depinde de mai muli
factori. Astfel, pentru a se evita buclarea, algoritmii trebuie s aib n vedere ca regula d s nu fie
aplicat la NS-uri care au mai fost solicitate. O topologie stea [16] este cea mai simpl soluie de
evitare a acestui fenomen.
Eficiena mecanismului DNS crete dac ordinea de specificare a NS-urilor vecine este bine aleas,
punnd pe primele locuri NS-urile mai frecvent folosite.
Mecanismul DNS nu este static, ci dinamic. Astfel, fiecare NS nva, innd minte solicitrile din
ultimele zile. Astfel, repetarea unor cereri face ca traseul de obine a unei adrese IP s fie mult
redus.
Specificarea adreselor Web (URL)
Un tip de adrese care extind adresele Internet sunt adresele de specificare a paginilor de Web [51].
Aceast specificare poart numele de URL (Uniform Resource Locator). O astfel de adres este de
forma:
protocol://server/cale/numedocument
Unele dintre aceste patru zone pot eventual s lipseasc.
protocol face parte dintre protocoalele comunicaiilor Internet, deci la nivelul de aplicaie
TCP/IP sau mai sus. Cel mai frecvent protocol este protocolul http (Hyper Text Transfer
Protocol) care este folosit pentru localizarea paginilor de Web.
server indic serverul care conine pagina de Web i se specific printr-o adres Internet aa cum
am prezentat n seciunea precedent.
cale/document este de fapt o specificare de fiier n stil UNIX [26,37]. Prin el se indic locul
documentului n structura de directori a serverului.
Iat, spre exemplu, cteva URL-uri:
http://www.ubbcluj.ro

SO2 - Comunicatii si SO distribuite

13

http://www.ubbcluj.ro/cluj.html
http://home.netscape.com/index.html
ftp://ftp.netscape.com/pub/ceva
news:news.announce.newusers
wais://cnidr.org/directory-of-server
gopher://gopher.micro.umn.edu/11/
Pentru detalii, se pot consulta lucrrile[32,35,20,21].

4 Elemente de limbaj HTML


4.1 Introducere
Limbajul HTML (HyperText Markup Language) este destinat scrierii documentelor de tip hipertext
care se pot vizualiza cu ajutorul navigatoarelor WWW (World Wide Web). Un document HTML
este un fiier text care folosete numai caractere ASCII, i poate fi realizat cu orice editor de texte
(de ex.: vi, pico, joe, emacs n sistemul de operare UNIX sau variantele acestuia, Notepad sub
Windows, BBEDit pe calculatoare Macintosh, editorul programului Norton Commander sau
editorul Edit sub DOS). Exist programe cu ajutorul crora textele HTML pot fi vizualizate, de ex.
HotMetal care poate fi utilizat pe mai multe platforme.
HTML este un limbaj bazat pe SGML (Standard Generalized Markup Language), un sistem
complex de descriere a documentelor. SGML este utilizat pentru descrierea structurii generale a
diferitelor tipuri de documente, fr s fie un limbaj de descriere a paginii (cum este PostScript).
Principala preocupare a SGML, deci i a HTML se rsfrnge asupra coninutului documentului, nu
asupra aspectului lui. Deci, n virtutea trsturilor motenite de la SGML, HTML este un limbaj
pentru descrierea documentelor structurate. Teoria din spatele acestui limbaj se bazeaz pe faptul c
majoritatea documentelor au elemente comune (titluri, paragrafe sau liste) i c dac defineti un set
de elemente, poi marca elementele documentului cu tag-urile (etichetele) corespunztoare.
Exist i programe cu ajutorul crora se pot realiza pagini web fr a cunoate limbajul HTML.
Acestea funcioneaz asemntor editoarelor de texte. Amintim aici doar editorul navigatorului
Netscape i programul FrontPage.
Recomandm scriitorilor de documente HTML s utilizeze programul HTMLTidy care este un
program gratuit aflat la: http://www.w3.org/MarkUp/Guide (dar i n pagina Web a
cursului), pentru a-i verifica, automat, corectitudinea textului scris.
Un document HTML poate conine text i marcaje. Marcajele HTML sunt de forma
<MARCAJ> ... </MARCAJ>

SO2 - Comunicatii si SO distribuite

14

Foarte rar partea final, </MARCAJ>, poate s lipseasc. Aceste marcaje nu sunt sensibile la tipul
literelor (majuscule sau minuscule). Aceasta nseamn c, de exemplu, urmtoarele marcaje
reprezint acelai lucru:
<HTML> ... </html>
<html> ... </HTML>
<Html> ... </hTmL>
Instruciunile HTML pot avea atribute cu sau fr valori. Atributele se scriu n felul urmtor:
<MARCAJ atribut_1[=valoare_1] atribut_2[=valoare_2]...>
unde elementele puse n paranteze drepte sunt opionale.
Nu intenionm s descriem toate marcajele i toate atributele lor, ci doar pe cele mai importante
dintre acestea. Cele dou tabele din anex prezint lista tuturor marcajelor permise n HTML 4.01,
lista tuturor atributelor, precum i marcajele n care acestea pot s apar. Considerm un exerciiu
util pentru nvarea HTML, ca cititorul s-i ntocmeasc un unic tabel cu sintaxele complete ale
HTML din combinarea celor dou tabele. De asemenea, cititorul are la dispoziie o serie de site-uri
Internet n care exte descris complet limbajul HTML. Adresa de referin n acest sens este:
http://www.w3.org/MarkUp/
Cu att mai mult, nu vom descrie acele marcaje sau atribute care sunt acceptate doar de un singur
navigator.
4.2 Un exemplu simplu de fiier HTML
Inainte de a prezenta limbajul HTML, preferm s prezentm un exemplu simplu de text HTML.
Iat mai jos un astfel de program.
<HTML>
<HEAD>
<TITLE> Document demonstrativ</TITLE>
</HEAD>
<BODY>
<H1> Salut! </H1>
Acesta este un document minimal HTML.
El arata structura de baza si conceptul de ancora.
<P>
Pentru informatii suplimentare despre HTML se pot consulta:
<A Href="http://www.december.com/html/">
http://www.december.com/htm/ </A>
sau se poate consulta <BR>E-cartea:
<A Href = " http://www.codec.ro/books/HTML/index.html/">
HTML 3.2 and CGI
Professional Reference Edition
UNLEASHED</A>
by John December and Mark Ginsburg <HR>
Daca doriti sa trimiteti un E-mail persoanei care a scris acest fisier,
va rog sa o faceti. Adresa este:
<ADDRESS> <A Href = "http://cs.ubbcluj.ro/~florin">Home pagina personala </A> si

SO2 - Comunicatii si SO distribuite

15

<A Href = "mailto:ubbadmin@ubbcluj.ro"> Adresa de E - mail </A> <BR> <HR>


</ADDRESS>
<B>Remarcati diferentele intre modul de scrierea in HTML si ceea ce apare pe
ecran.
</B>
</BODY>
</HTML>

Fiierul FirstHTML.html
Acest fiier, deschis cu navigatorul Netscape, apare ca n fig. 5.1

Figura 5.1 Vizualizarea fiierului FirstHTML.html


Dup cum se vede, un fiier HTML apare ca un text ce conine o serie de construcii delimitate de
simbolurile "<" i ">". Aceste construcii specific indicaii speciale adresate navigatorului
(browserului) Web. Orice construcie care apare ntre simbolurile "<" i ">" o vom numi marcaj sau
tag. n sperana c nu vor exista confuzii, i pentru c este mai scurt, vom folosi de multe ori
termenul de tag n loc de marcaj (natural, marcaj i tag vor nsemna acelai lucru).
Tagurile sunt de dou feluri:
Taguri simple, indicate prin construcii de forma:
<NumeTag AtributeTag>
Taguri compuse, indicate prin construcii de forma:
<NumeTag AtributeTag> TextAfectatDeTag </NumeTag>

n textul HTML de mai sus tagurile <P>, <BR> i <HR> sunt taguri simple. Efectul lor este
respectiv: nceputul unui nou paragraf, trecerea la un rnd nou (break row) i trasarea unei linii

SO2 - Comunicatii si SO distribuite

16

orizontale (horizontal row). n acelai text, apar tagurile compuse: HTML, HEAD, TITLE, BODY,
H1 etc.
4.3 Structura unui document HTML

4.3.1 Antet, fond i culori


Exist cteva marcaje care sunt obligatorii ntr-un document HTML. Acestea sunt urmtoarele:
<HTML> ... </HTML>
<HEAD> ... </HEAD>
<BODY> ... </BODY>
Un document HTML poate fi de forma:
<HTML>
<HEAD>
aici apare textul antetului
</HEAD>
<BODY>
aici apare textul corpului documentului
</BODY>
</HTML>
n textul unui document HTML spaiile nu au importan, deci printr-o indentare potrivit textul
poate fi mai lizibil. Este de remarcat faptul, c diferite navigatoare pot vizualiza textele n moduri
diferite.
<HTML> ... </HTML> Acest marcaj are rolul de a delimita textul dintr-un document HTML.
Singurele marcaje care pot s apar direct n interiorul lui <HTML> sunt <HEAD> si <BODY>.
<HEAD> ... </HEAD> Reprezint antetul unui document HTML i conine o colecie de
informaii despre document. In interiorul acestuia pot s apar mai multe marcaje. Aici le
menionm doar pe urmtoarele:
<BASE HREF="adresa"> Un document HTML poate s conin legturi nspre alte documente
HTML. Aceste documente pot s fie specificate printr-o adres complet, de exemplu
http://www.domeniu.ro/director/document.html
sau intr-o form parial, ca de exemplu:
director/document.html

(*)

SO2 - Comunicatii si SO distribuite

17

Dac este declarat un marcaj <BASE>, atunci adresele pariale specificate n document sunt
completate cu adresa menionat n <BASE>. n caz contrar acestea sunt completate cu adresa
documentului curent. De exemplu, dac adresa documentului curent este
http://www.altdomeniu.ro/dir/doc.html
i nu exist <BASE>, atunci adresa specificat mai sus (*) se va completa la
http://www.altdomeniu.ro/dir/director/document.html
Dac ns exist:
<BASE HREF="http://www.domeniu.ro/">
atunci adresa specificat mai sus (*) se va completa la
http://www.domeniu.ro/director/document.html
<TITLE>...</TITLE> Orice document HTML trebuie s aib un titlu. Titlul este un ir de
caractere arbitrar care identific coninutul documentului. Titlul trebuie s apar n interiorul
marcajei <HEAD>.
<META...> Instruciunea <META> este folosit n interiorul lui <HEAD> pentru a introduce
informaii care nu sunt definite de alte marcaje HTML. Aceste informaii pot fi extrase de
servere/clieni pentru a fi utilizate n identificarea, indexarea i catalogarea documentelor. Dintre
atributele care pot s apar n interiorul unei marcaje <META> menionm aici doar NAME i
CONTENT. Iat cteva exemple:
<META NAME="description" content="Ion I. Ionescu este cercetator
la Institutul X. Aceast pagin conine detalii despre activitatea
sa">
<META NAME="keywords" CONTENT="cuvnt-cheie-1,
cuvnt-cheie-3, i-alte-cuvinte-cheie">

cuvnt-cheie-2,

<BODY>...</BODY> Conine ntregul text i imaginile care formeaz pagina de Web, mpreun
cu toate marcajele HTML care controleaz formatarea paginii. In interiorul marcajului <BODY> pot
s apar anumite atribute care controleaz schema de culori a documentului. n continuare
prezentm cele mai importante atribute.
BACKGROUND="URL-al-unui-fiier-ce-conine-o-imagine"
Imaginea din fiierul specificat este pus cap la cap i formeaz n acest fel fundalul documentului.
n lipsa acestui atribut fundalul va avea culoarea specificat n BGCOLOR.
BGCOLOR="#rrvvaa"

SO2 - Comunicatii si SO distribuite

18

Specific culoarea fundalului documentului, unde #rrvvaa este un triplet scris in hexazecimal
care reprezint ponderea culorilor rou-verde-albastru n culoarea dorit (rr=00 nseamna absena
complet a culorii roii, iar rr=FF nseamn prezent total a culorii roii). Valoarea implicit este
cea alb.
TEXT="#rrvvaa"
Specific culoarea textului normal din document.
LINK, VLINK, ALINK
Un document HTML poate s conin legturi nspre alte docuemte HTML sau imagini. Aceste
atribute controleaz culorile textului care reprezint legtura, astfel:
LINK reprezint culoarea textului corespunztor unei legturi nevizitate,
VLINK reprezint culoarea textului corespunztor unei legturi vizitate i
ALINK reprezint culoarea textului unei legturi vizitate i active (documentul este deja n
memoria Cache a navigatorului). Culorile implicite pentru aceste texte sunt, n ordinea menionat,
albastru (#0000FF), roz (#400040) i rou (#FF0000). Sintaxa acestor atribute este acceai cu cea a
atributului TEXT.
Dm n continuare o list de culori mai frecvente. De menionat c se pot folosi i denumirile
englezeti ale culorilor, de exemplu, n loc de "#FF0000" se poate scrie pur i simplu red.
negru
000000
(black)
rou
FF0000
(red)
alb
FFFFFF
(white)
verde
00FF00
(green)
albastru
0000FF
(blue)
albastru violet 9F5F9F
(blue violet)
galben
FFFF00
(yellow)
maro
A62A2A
(brown)
verde nchis
2F4F2F
(dark green)
albastru deschis C0D9D9
(light blue)
maro nchis
5C4033
(dark brown)
portocaliu
FF7F00
(orange)
auriu
CD7F32
(gold)
gri
C0C0C0
(grey)
violet
4F2F4F
(violet)

Modul cel mai simplu de a vizualiza un document HTML este folosind Netscape. Lansm
programul Netscape i ncrcm fiierul care conine documentul prin intermediul meniului File |
Open File.

4.3.2 Marcaje de formatare a documentului


Din punctul de vedere al formatrii unui document HTML, lucrurile stau foarte asemntor cu
preparatorul de texte matematice LaTeX. Aceasta nseamn c textul dintr-un document HTML se
formateaz exclusiv conform marcajelor de formatare incluse n text. Formatul fizic pe care l dm
noi documentului (caractere TAB, caractere spaiu multiple, caractere NEWLINE) nu este luat n
seam de navigatoarele Web. n aceast seciune vom prezenta cele mai importante marcaje de

SO2 - Comunicatii si SO distribuite

19

formatare HTML. Dac sunt prezente, acestea trebuie s apar exclusiv n corpul documentului
(ntre <BODY> i </BODY>).
<ADDRESS>...</ADDRESS> Specific informaii cum ar fi adresa sau autorul unui document i
se plaseaz de obicei la nceputul sau sfritul documentului. De obicei, textul corespunztor se
formateaz n italic i poate s fie indentat. Navigatoarele Web vor presupune c acesta formeaz un
paragraf separat.
<BLOCKQUOTE>...</BLOCKQUOTE> Se folosete pentru introducerea de informaii citate din
alte surse. Textul va apare cu indentare la stnga i la dreapta i, de obicei, n italic. Este un paragraf
separat.
<BR> Foreaz ruperea liniei. Textul care urmeaz se va scrie de la nceputul liniei urmtoare.
<CENTER>...</CENTER> Toate liniile de text dintre <CENTER> i </CENTER> sunt centrate
ntre marginile din stnga i dreapta, n loc s fie aliniate la stnga i la dreapta, cum este normal.
<FONT ...> ... </FONT> Permite setarea sau schimbarea dimensiunii fontului, culorii i tipului
textului. Aceste operaii se realizeaz prin intermediul ctorva atribute, pe care le vom prezenta n
continuare:
SIZE=[+|-]valoare
Permite modificarea dimensiunii fontului (valoare este un numr ntre 1 i 7).
Dac se folosete + sau - fontul se modific relativ fa de dimensiunea de baz.
COLOR=#rrvvaa Permite specificarea culorii textului.
FACE=nume [,nume ,nume ...]
Permite specificarea unui tip de caractere pentru textul respectiv i,
deasemenea, cteva tipuri alternative n caz c acesta nu este disponibil.
Exemplu:
<FONT SIZE=+1 COLOR=red> text </FONT>
<Hx> ... </Hx> unde x este un numr ntre 1 i 6, definete unul din cele ase nivele de titluri
(de capitol, seciune, subseciune .a.m.d.). Instruciunea <Hx> presupune schimbarea fontului,
spaii nainte i dup titlu i declararea textului respectiv ca paragraf.
Unele navigatoare accept folosirea atributului ALIGN pentru alinierea textului n mod
corespunztor. Acest atribut are forma
<Hx ALIGN=left> Titlu de nivelul x aliniat la stanga </Hx>
<Hx ALIGN=center> Titlu de nivelul x centrat </Hx>
<Hx ALIGN=right> Titlu de nivelul x aliniat la dreapta </Hx>

sau
sau

<HR> Deseneaz o linie orizontal ca separator ntre diferite seciuni de text. Poate s aib mai
multe atribute, dintre care amintim:
<HR SIZE=numar>
Grosimea liniei, n pixeli.
<HR WIDTH=numar[%]>
Lungimea liniei, fie n pixeli (dac nu exist caracterul %), fie n
procente din limea total a paginii (dac exist caracterul %). (Semnele [ ] delimiteaz un text
opional)

SO2 - Comunicatii si SO distribuite

20

<HR ALIGN=left|right|center>
n cazul n care linia orizontal este mai mic dect limea paginii, acest
atribut permite specificarea modului de aliniere a liniei. (Semnul | delimiteaz cuvintele care pot fi
alease ca valoarea atributului).
<NOBR>...</NOBR> Textul dintre <NOBR> i </NOBR> nu poate fi rupt pe mai multe linii.
Prin urmare, ntr-o astfel de situaie ar fi posibil ca utilizatorul s fie nevoit s ajusteze dimensiunea
paginii navigatorului.
<P>...</P> Aceast instruciune indic un paragraf. Deoarece nceputul unui paragraf este, n
acelai timp, i sfritul paragrafului precedent, </P> se poate omite. De-asemenea, are un atribut,
ALIGN, care indic modul de aliniere a textului din paragraful respectiv:
<P ALIGN=left|center|right> ... </P>
<PRE>...</PRE> Textul dintre <PRE> i </PRE> este afiat aa cum este el redactat, fr a
mai fi formatat de navigator (deci aici i spaiile sunt luate n considerare). De exemplu, aceast
instruciune se poate folosi pentru introducerea de texte surs ntr-un document HTML. Are un
singur atribut, WIDTH, care indic numrul de caractere dintr-o linie, cu valoarea implicit de 80:
<PRE WIDTH=numar> ... </PRE>

4.3.3 Specificare tip i format caractere


n seciunea de fa descriem dou tipuri de marcaje de formatare:
(a) Marcaje de formatare logic. Acestea sugereaz navigatorului c decizia de formatare a textul
respectiv trebuie luat de ctre acesta, i nu de ctre autorul documentului HTML.
(b) Marcaje de formatare fizic. Aceste marcaje impun navigatorului un anumit tip de formatare.
In cele ce urmeaz vom trece n revist cele mai importante marcaje de formatare. Vom ncepe cu
marcajele de formatare logic:
<CITE>...</CITE> Specific o citare. In mod normal se scrie n italic. Textul respectiv nu se
separ ca paragraf separat, i nici nu se ia vre-o decizie alta dect schimbarea stilului caracterelor
textului.
<EM>...</EM> Specific text redactat cu emfaz. In mod normal se scrie n italic.
<KBD>...</KBD> Indic text tiprit de utilizator. De obicei se folosete ntr-un manual de
marcaje. n mod normal se scrie monospaiat. Aceasta nseamn c fiecare caracter se scrie ntr-un
ptrat de dimensiuni egale. De exemplu, literele i i m vor ocupa acelai spaiu.
<STRONG>.. </STRONG> Specific text redactat cu emfaz puternic, i n mod normal se
scrie n bold (caractere ngroate).
<VAR>...</VAR> Indic nume de variabil. De obicei se scrie n italic.

SO2 - Comunicatii si SO distribuite

21

<!-- Comentarii --> Textul dintre irul <!-- i urmtoarea apariie a irului --> nu este
procesat navigator. Se accept spaii ntre -- i > la delimitatorul de sfrit al comentariului, dar
nu ntre <! i -- la delimitatorul de nceput.
n continuare prezentm marcajele de formatare fizic:
<B> ... </B>
Textul se scrie n bold.
<I> ... </I>
Textul se scrie n italic.
<TT> ... </TT>
Textul se scrie n fontul typewriter.
<U> .. </U>
Textul se scrie subliniat.
Textul se scrie cu o linie orizontal suprapus.
<STRIKE>...</STRIKE>
<SUB> ... </SUB> Textul se scrie ca indice inferior i cu dimensiune mai mic.
<SUP> ... </SUP> Textul se scrie ca indice superior i cu dimensiune mai mic.
<BIG> ... </BIG> Textul se scrie utiliznd un font de o dimensiune mai mare.
<SMALL>...</SMALL> Textul se scrie utiliznd un font de o dimensiune mai mic.

4.3.4 Scrierea caracterelor ne-standard


Scrierea anumitor caractere ntr-un document HTML necesit utilizarea unor secvene speciale,
deoarece acestea fie sunt caractere cu semnificaie special n sintaxa comenzilor HTML, fie sunt
caractere ne-latine, fie sunt caractere latine cu semne diacritice.
Aceste caractere se specific printr-o secven tip, de forma &ir; (caracterul ampersand, urmat de
un ir de caractere, urmat de caracterul punct-virgul). In continuare vom descrie modul n care pot
fi specificate aceste seturi de caractere.
Caractere speciale, sunt n numr de patru:
<
>
&
"

se scrie ca

&lt;
&gt;
&amp;
&quot;

Caractere specifice unor limbi. Sunt disponibile foarte multe caractere. Marea lor majoritate se
specific dup modelul urmtor:
&lsemn;
unde l este litera de baz (mare sau mic), iar semn este o descriere a semnului diacritic care se
pune deasupra sau dedesubtul caracterului. Iat descrierile semnelor care pot s apar:
&#atilde; caracterul romnesc;
caracterul romnesc;
&#226;
caracterul romnesc;
&#174;
caracterul romnesc;
&#351;
caracterul romnesc;
&#355;
acute
pentru
accent ascuit;

SO2 - Comunicatii si SO distribuite

cedil
circ
grave
ring
tilde
uml

22

sedil;
accent circumflex;
accent grav;
inel;
tilda;
umlaut (dou puncte orizontale).

De exemplu, cuvntul main se scrie ntr-un document HTML n acest fel: ma&351;in&atilde;.
Urmtoarele patru caractere merit, de-asemenea, menionate:
&reg;
&copy;
&trade;
&nbsp;
cuvinte!

este echivalent cu semnul de marc nregistrat;


semnul de copyright;
emnul de marc comercial;
caracterul spaiu, care ns nu este interpretat de navigator ca i separator de

Caractere specificate prin codul ASCII


Caracterele ASCII se pot specifica i prin codul lor numeric, n felul urmtor:
&#nn;
unde nn este codul ASCII al caracterului respectiv, scris n baza 10, cuprins ntre 0 i 255. Facem
meniunea c acest numr trebuie s aib cel puin dou cifre; dac este nevoie, numrul se
completeaz cu un zero nesemnificativ.
Iat cteva exemple,
&#38;
&#162;
&#163;
&#164;
&#165;
&#167;
&#169;
&#174;

este echivalent cu

&amp;
centul american;
lira englez;
dolarul american;
yenul japonez;
semnul de seciune;
semnul de copyright;
semnul de marc nregistrat.

4.4 Legturi hipertext


<A...>...</A> Instruciunea ancor este esenial ntr-un document HTML. Textul dintre
<A...> i </A> este textul de activare a legturii respective. Acest text se numete hipertext.
Utilizatorul va da click cu mouse-ul pe hipertextul respectiv, iar n urma acestei operaii navigatorul
va executa una din aciunile specificate de atributele prezente n <A...>. Dintre toate atributele,
fie NAME fie HREF sunt obligatorii. Iat n continuare cele mai importante atribute:

SO2 - Comunicatii si SO distribuite

23

<A HREF="url"> ... </A>


La selectarea acestui hipertext navigatorul va afia documentul specificat prin URL-ul respectiv. n
loc s ne deplasm la un alt document, putem s ne deplasm la un anumit punct al acelui document
sau al documentului curent. Aceste puncte se numesc ancore i se pot defini folosind atributul
NAME:
<A NAME="ancor"> ... </A>
Admind c aceast ancor a fost creat n documentul specificat prin URL-ul "url", referirea la
aceast ancor se va face astfel:
<A HREF="url#ancor"> ... </A>
Dac ns ancora a fost creat n documentul curent, referirea se va face astfel:
<A HREF="#ancor> ... </A>
Mai amintim aici c formele pe care le poate lua URL-ul "url" n cadrul atributului HREF sunt cele
definite de sintaxa URL. Le menionm doar pe cele mai interesante:
<A HREF="http://...">
<A HREF="ftp://...">

Salt la un alt document HTML


Realizeaz o conexiune prin ftp anonim la un server
ftp.

<A HREF="ftp://login:pass@...">
Conexiunea la serverul ftp se face utiliznd contul "login" i parola "pass"; dac parola
lipsete, se va cere explicit.
<A HREF="mailto:user@domeniu.ro">
Activarea acestei legturi deschide aplicaia de redactare i expediere a unui mesaj electronic
ctre
user@domeniu.ro.
<A HREF="news:...">
Realizeaz o legtur la un newsgrup.
<A HREF="telnet:...">
Activarea acestei legturi iniiaz o
sesiune telnet cu maina specificat.
Exemplu: Dac n text apare legtura hipertext:
<A HREF="http://www.ubbcluj.ro">Universitatea Babes-Bolyai din Cluj </A>
navigatorul va vizualiza textul Universitatea Babes-Bolyai din Cluj cu culoare specificat n LINK,
i n urma unui clic cu mouse-ul pe acest text se va vizualiza hipertextul de la adresa menionat.

4.5 Liste i tabele


4.5.1 Marcaje de tip list

SO2 - Comunicatii si SO distribuite

24

HTML suport cteva tipuri de liste. Toate acestea pot fi imbricate, i trebuie s apar n corpul
unui document HTML.
<DL>...</DL> Reprezint o list de definiii. Fiecare termen de definit se precede de <DT>, iar
definiia respectiv se precede de <DD>. Se folosete dup modelul urmtor:
<DL>
<DT> Termen 1 <DD> Definiia termenului 1.
<DT> Termen 2 <DD> Definiia termenului 2.
</DL>
Rezultatul va fi:
Termen 1
Definiia termenului 1.
Termen 2
Definiia termenului 2.

<OL>...</OL> Reprezint o list numerotat. Fiecare element al listei se precede de <LI>. Se


folosete dup modelul urmtor:
<OL>
<LI> Primul termen;
<LI> Al doilea termen.
</OL>
Rezultatul va fi:

1. Primul termen;
2. Al doilea termen.

n mod normal numerotarea ncepe de la 1 i numrul de ordine se afieaz folosind numerele


obinuite: 1, 2, 3, .... Dac dorim modificarea acestor lucruri, putem folosi atributele START i
TYPE:
<OL START=numar> Specific numrul de nceput al numerotrii.
<OL TYPE=caracter> Specific modul de numerotare. Caracterul poate fi A (la
numerotare se folosesc litere mari: A, B, C,...), a (litere
mici:
a, b, c,...), I (numere romane mari: I, II,
III,...), i (numere
romane mici: i, ii, iii,...), 1
(numere obinuite: 1, 2, 3,...).
<UL>...</UL> Reprezint o list nenumarotat. Fiecare element al listei se precede de <LI>.
Se folosete dup modelul urmtor:

SO2 - Comunicatii si SO distribuite

25

<UL>
<LI> Primul termen;
<LI> Al doilea termen.
</UL>
Rezultatul va fi:
* Primul termen;
* Al doilea tremen.

In mod normal fiecare element al listei se precede de un caracter special care variaz n funcie de
nivelul listei: disc solid, cerc, ptrat etc. Pentru modificarea acestui caracter special se poate folosi
atributul TYPE:
<UL TYPE=disc|circle|square>
<MENU>...</MENU> Reprezint o list de elemente, cte una pe linie. Este foarte asemntor cu
<UL>...</UL>, deosebirea constnd n faptul c lista <MENU> este mai compact dect lista
<UL>. Se folosete dup modelul urmtor:
<MENU>
<LI> Primul termen.
<LI> Al doilea termen.
</MENU>
Listele pot fi imbricate. De exemplu:
<UL>
<LI> Primul nivel 1
<UL>
<LI> Al doilea
<LI> Al doilea
</UL>
<UL>
<LI> Primul nivel 2
<UL>
<LI> Al doilea
<LI> Al doilea
</UL>
</UL>

nivel 1
nivel 2

nivel 3
nivel 4

Reazultatul va fi:
* Primul nivel 1
+ Al doilea nivel 1
+ Al doilea nivel 2

SO2 - Comunicatii si SO distribuite

26

* Primul nivel 2
+ Al doilea nivel 3
+ Al doilea nivel 4

4.5.2 Tabele
ntr-un document HTML se pot introduce i tabele. Vom prezenta marcajele necesare i apoi vom
vedea i un exemplu.
<TABLE...>...</TABLE> Este marcajul principal care definete un tabel. Toate celelalte
marcaje trebuie s apar n interiorul acesteia. Are urmtoarele atribute mai importante:
grosimea bordurii n pixeli; valoarea implicit este 0, adic fr
BORDER=nr
bordur;
controleaz spaiul dintre celulele tabelului; valoarea este
CELLSPACING=nr
dat n pixeli;
controleaz spaiul dintre datele din celul i pereii
CELLPADDING=nr
celulei; valoarea este dat n pixeli;
WIDTH=nr[%]
specific limea tabelului, fie n pixeli, fie n procente de lime
a ferestrei;
specific nlimea tabelului, fie n pixeli, fie n procente de
HEIGHT=nr[%]
nlime a ferestrei;
<TR...>...</TR> Specific un rnd de celule al tabelului. Numrul de rnduri este dat de
numrul de perechi <TR>...</TR>. Are urmtoarele atribute mai importante:
ALIGN=left|center|right
controleaz modul de aliniere pe orizontal a textului n interiorul celulelor;
VALIGN=top|middle|bottom|baseline
controleaz modul de aliniere pe vertical a textului n celule;
<TD...>...</TD> Specific o celul de date a tabelului. Trebuie s apar doar n interiorul unui
rnd (ntre <TR> i </TR>). Dintre atributele mai importante menionm:
ALIGN=left|center|right
controleaz modul de aliniere pe orizontal a textului n interiorul celulei;
valoarea implicit este left;
VALIGN=top|middle|bottom|baseline
ontroleaz modul de aliniere pe vertical a textului n interiorul celulei;
valoarea implicit este middle;
specific limea tabelului, fie n pixeli, fie n procente de lime
WIDTH=nr[%]
a tabelului;
HEIGHT=nr[%] specific nlimea tabelului, fie n pixeli, fie n procente de
nlime a tabelului;
rndurile lungi nu se pot rupe;
NOWRAP
specific numrul de coloane peste care se va ntinde celula
COLSPAN=nr
aceasta;

SO2 - Comunicatii si SO distribuite

ROWSPAN=nr

27

specific numrul de rnduri peste care se va ntinde celula

aceasta.
<TH...>...</TH> Specific o celul antet a tabelului. Este absolut identic cu o celul <TD>
cu singurele diferene c textul din interiorul celulei <TH> este bold i este implicit aliniat cu
ALIGN=center.
<CAPTION...>...</CAPTION> Este titlul tabelului. Trebuie s apar n interiorul lui
<TABLE>, dar nu n interiorul rndurilor sau celulelor. Accept atributul
ALIGN=top|bottom controleaz locul unde se va scrie titlul respectiv (deasupra sau
sub tabel).
Iat mai jos descrierea a dou tabele:
<html>
<head>
<title>exemple de tabele</title>
</head>
<body>
<TABLE BORDER>
<TR>
<TD>Celula 1</TD>
<TD COLSPAN=2>Celul pe dou coloane</TD>
</TR>
<TR>
<TD>Celula 2</TD>
<TD>Celula 3</TD>
<TD>Celula 4</TD>
</TR>
<CAPTION ALIGN=bottom>Titlul tabelului</CAPTION>
</TABLE>
<TABLE BORDER>
<TR>
<TH ROWSPAN=2></TH>
<TH COLSPAN=3>Browser</TH>
</TR>
<TR>
<TH>Netscape</TH>
<TH>Internet Explorer</TH>
<TH>Mosaic</TH>
</TR>
<TR>
<TH ROWSPAN=2>Element</TH>
<TD>-</TD>
<TD>X</TD>
<TD>-</TD>
</TR>
<TR>
<TD>X</TD>
<TD>X</TD>
<TD>X</TD>
</TR>
</TABLE>
</body>
</html>

SO2 - Comunicatii si SO distribuite

28

Figura 5.2 prezint imaginea celor dou tabele vizualizat de Internet Explorer.

Figura 5.2. Imaginea a dou tabele


4.6

Introducerea de imagini

Navigatoarele actuale permit utilizarea formatelor grafice .GIF i .JPG pentru ncrcarea de imagini.
Microsoft Internet Explorer permite n plus utilizarea formatelor grafice .PNG (portable network
graphics) i .BMP. Netscape i Internet Explorer permit utilizarea fiierelor grafice multi-imagine
.GIF, ceea ce permite crearea de secvene animate.
Imaginile posibile ntr-un document HTML sunt de dou tipuri:
Imagini inline, care apar direct n pagin odat cu ncrcarea paginii. O astfel de imagine se
specific fie printr-un tag <IMG >, fie printr-un alt mecanism, de exemplu ntr-un tag <INPUT
...> dintr-un formular. De exemplu, o specificare de forma:
<IMG Src = "romap.gif">
provoac inserarea n textul paginii a hrii cu judee a Romaniei (fiierul se afl n pagina cursului).
Imagini externe, care vor fi ncrcate la cererea utilizatorului, printr-o ancor corespunztoare. De
exemplu, o specificare de forma:
<A Href = "romap.gif">harta</A>

SO2 - Comunicatii si SO distribuite

29

provoac afiarea aceleiai hri, ntr-o pagin separat, atunci cnd utilizatorul d clic pe cuvntul
harta.
<IMG ...> Se utilizeaz la introducerea de imagini. De remarcat c instruciunea nu are un
element de genul </IMG>. Iat, n continuare, atributele mai importante:
SRC="url"
WIDTH=numr
HEIGHT=numr

Specific URL-ul fiierului ce conine imaginea de afiat.


Specific limea imaginii n pixeli.
Specific nalimea imaginii n pixeli.

De remarcat c, dei nu este necesar, este bine s se foloseasc aceste ultime dou atribute, deoarece
astfel utilizatorul nu va atepta preluarea complet a imaginii nainte de afiarea textului. La aceste
ultimele dou atribute se poate folosi i % dup numr, n acest caz imaginea se mrete (numr
peste 100%) sau se micoreaz (numr sub 100%) corespunztor.
BORDER=numr Specific grosimea bordurii imaginii, n pixeli. Valoarea
implicit este 0 (fr bordur).
ALT="text"
Specific un text alternativ care se afieaz n navigatoare negrafice, sau cnd navigatorul grafic are anulat facilitatea de ncrcare a imaginilor.
ALIGN=valoare Specific diferite moduri de aliniere a imaginii. Dintre toate
valorile posibile, prezentm aici urmtoarele:
left Deplaseaz imaginea la marginea stng.
right
Deplaseaz imaginea la marginea dreapt.
top
Se aliniaz cu marginea de sus a elementului cel mai nalt din linia curent.
absmiddle
Aliniaz mijlocul liniei curente cu mijlocul imaginii.
absbottom
Aliniaz partea de jos a liniei curente cu partea de jos a imaginii.
Exemplu:
<IMG SRC="univers.gif" ALT="Imaginea universitatii">
La vizualizare ncrcarea unei imagini poate dura mai mult. Dac dorim a vizualizare mai rapid
putem decupla n navigator ncrcarea automat a imaginilor. n acest caz vizualizarea se face
numai dac facem un clic pe iconul care ascunde imaginea.
Se poate alege o soluie mai elegant, i anume includerea unei imagini mici, care se poate mri
fcnd un clic pe ea. De exemplu:
<A HREF="mare.gif">

<IMG SRC="mic.gif"> </A>

Aici "mic.gif" reprezint o imagine de mrime mic care se vizualizeaz automat (dac nu este
decuplat opiunea respectiv), i se ncarc imaginea "mare.gif", care este aceeai imagine dar
de mrime mai mare, i care se ncarc n urma unui clic pe imaginea mic.

SO2 - Comunicatii si SO distribuite

30

5 Interaciuni HTML
Din cele descrise mai sus privind limbajul HTML, se poate descrie orice document care s fie
gzduit pe un server Web i s se navigheze prin el de ctre orice client Web folosind un navigator
oarecare.
Se poate ns observa uor c de la client nu se poate trimite nimic spre server, cu excepia
comenzilor de ncrcare de noi documente prin intermediul ancorelor.
Exist n HTML dou posibiliti prin care clientul poate transmite informaii ctre server:
formularele HTML i hrile senzitive asociate imaginilor. Le vom prezenta pe rnd.
5.1 Formulare HTML

5.1.1 Principiul de funcionare


Formularele sunt instrumentul principal HTML de interaciune cu utilizatorul. El furnizeaz o serie
de faciliti grafice de preluare de informaii de la utilizator, cum ar fi: csue de dialog, butoane
radio, liste de opiuni etc. Dup exprimarea opiunilor de ctre utilizator, acestea sunt transmise
unui program specializat, numit CGI (Common Gateway Interchange). Acest CGI la rndul lui
poate interaciona cu fiiere, baze de date etc. aflate pe serverul de Web. Ca rezultat al execuiei,
CGI d la ieire, spre browser, un nou text HTML. n figura 6.1 este prezentat aceast relaie.
Figura 6.1 Relaia CGI - HTML

Limbajele folosite pentru CGI pot fi: C, C++, Java (aplicaii stand-alone), scripturi Shell, Scripturi
Perl etc. Indiferent de limbaj, trebuie precizat modalitatea de primire a informaiilor de ctre CGI
de la formular i modalitatea de rspuns.

SO2 - Comunicatii si SO distribuite

31

Datele de intrare sunt primite de CGI sub forma unei linii de text. Programul trebuie s priveasc
aceast linie fie ca primul parametru al liniei de comand (metoda Get) fie ca prima linie din fiierul
de intrare standard (metoda Post).
Datele de ieire din CGI sunt invariabil furnizate de ctre browser ca i un text HTML sau orice alt
tip de document inteligibil n browser, furnizat de CGI prin ieirea standard.

5.1.2 Un exemplu simplu de formular


Exemplul pe care-l vom prezenta este urmtorul. Vom cere printr-un formular ca userul s-i dea
numele de user i parola. Serverul va ntoarce irul de caractere pe care l-a primit de la formular.
Pentru aceasta, sunt necesare mai multe fiiere. Astfel, n subdirectorul public_html al
directorului gazd exist fiierul index.html. Coninutul acestuia este:
<HTML>
<HEAD>
<TITLE>Verificare user si parola</TITLE>
</HEAD>
<BODY>
<FORM METHOD="post" ACTION=/cgi-bin/TestCgi.cgi>
<P>Login:<INPUT NAME="Login"></INPUT>
Password:<INPUT TYPE="password" NAME="Password"></INPUT>
<INPUT TYPE="submit" VALUE="Login">
<INPUT TYPE="reset" VALUE="Cancel">
</FORM>
</BODY>
</HTML>

Fiierul index.html
Lansarea lui n execuie cu Internet Explorer are ca efect imaginea din fig. 6.2.
Dup completarea cmpurilor Login i Password, se va da clic pe butonul Login. Ca efect, va
fi lansat n execuie programul cu numele TestCgi.cgi situat n subdirectorul standard cgibin al directorului standard al serverului Web (de regul, sub Linux, acesta este
/home/httpd/). Acesta este de fapt un program CGI.

Figura 6.2 Imaginea iniial a formularului

SO2 - Comunicatii si SO distribuite

32

n acest exemplu, am folosit ca limbaj suport pentru CGI limbajul C sub Unix. Coninutul acestui
program este uor de neles, el tiprind la ieirea standard, pur i simplu textul HTML de rspuns:
#include <stdio.h>
main () {
char DeLaFormular[1000]; // Aici se citeste mesajul formularului
fgets(DeLaFormular, 1000, stdin); //Citeste din intrarea standard
// linia primita de la formular
printf("Content-type: text/html");// Trei linii standard
printf("\n");
// cerute de
printf("\n");
// protocolul HTTP
printf("<HTML>");
// Urmeaza tiparirea la iesirea standard
printf("<HEAD>");
// a documentului HTML de raspuns
printf("<TITLE>");
printf("Raspunsul de la CGI");
printf("</TITLE>");
printf("</HEAD>");
printf("<BODY>");
printf("<H3>");
printf("CGI a primit stringul:");
printf("</h3>");
printf("%s",DeLaFormular);
printf("</BODY>");
printf("</HTML>");
}

Fiierul TestCgi.c
Dac transmiterea cererii se fcea folosind metoda GET, atunci n locul lui fgets s-ar fi pus:
strcpy(DeLaFormular, getenv("QUERY_STRING"));

Dup compilare, fiierului executabil i se va atribui numele TestCgi.cgi i va fi depus n directorul


~florin/public_html/cgi_bin
Dup completarea numelui de user, aici florin, i a unei parole, aici am dat drept parol textul "o
parola oarecare", se d click pe butonul Login. Imaginea rspuns dat de CGI pe navigator
va fi cea din fig. 6.3.

Figura 6.3 Rezultatul ntors de CGI


In cazul apelului CGI prin metoda GET, URL-ul de apel ar fi fost:

SO2 - Comunicatii si SO distribuite

33

http://www.cs.ubbcluj.ro/~florin/cgi-bin/TestCgi.cgi?Login=florin&Password=o+parola+oarecare

5.1.3 Principalele taguri folosite la formulare HTML


Tagul <FORM are sintaxa:
<FORM Action="URL" Method="get|post" [ Enctype="string" ] >
Continutul formularului
</FORM>

Action indic URL-ul programului CGI care va fi lansat la execuia formularului. Majoritatea
serverelor Web pretind ca acest CGI s fie plasat ntr-un loc anume n structura de directori, iar
drepturile asupra lui s fie acordate de ctre administrator. Evident, aceast cerin apare din motive
de securitate. n exemplul de mai sus CGI este plasat n mod standard de ctre serverul Web
Apache.
Method indic metoda care este folosit de formular spre a transmite informaiile spre CGI. Aa
cum am artat mai sus, prin get se transmite ca primul argument al liniei de comand, iar prin
post ca i prim linie a intrrii standard.
Enctype indic modalitatea de reprezentare a informaiilor culese prin formular. De regul acest
atribut lipsete, iar informaiile sunt prezentate ntr-o form standard. n cele ce urmeaz vom
prezenta acest standard de reprezentare. CGI primete de la formular o singur linie de text ASCII,
cu urmtoarele caracteristici:
Fiecare cmp al formularului furnizeaz o pereche nume=valoare (semnul = separ numele de
valoare).
Dou perechi nume=valoare sunt separate ntre ele prin semnul &.
Caracterele nonalfanumerice sunt nlocuite prin %xx, unde xx sunt dou cifre hexazecimale
reprezentnd codul caracterului ASCII. In acest context, pentru a se indica separarea a dou linii de
informaie, ntre ele apare %0D%0A.
Toate caracterele spaiu din nume sau valoare sunt nlocuite prin caracterul +.
n coninutul formularului se specific, printre altele, tagurile <INPUT, <SELECT, <OPTION i
<TEXTAREA, pe care le vom prezenta n continuare. n corpul unui formular nu poate s fie
definit un alt formular!.
Tagul <INPUT este instrumentul fundamental de specificare i obinere a intrrilor de la utilizator.
Prin facilitile lui, ofer practic toate modalitile de intrare oferite de GUI actuale (de sub
Windows, X Window etc.). Sintaxa tagului este:
<INPUT
Type="text|password|radio|checkbox|image|hidden|submit|reset"
Name="string" Value="string" Checked Src="URL" Text
Size="n" Maxlength="n" Align="top|middle|bottom" >

Semnificaia atributelor lui <INPUT este:

SO2 - Comunicatii si SO distribuite

34

Type definete tipul cmpului de intrare prezentat utilizatorului. Fiecare dintre cele opt cuvinte
posibile indic un mod de preluare a informaiilor, astfel:
text indic colosirea pentru intrare a unei singure linii de text. Se folosesc la dimensionare i
atributele Size i Maxlength (dac sunt prezente).
password indic preluarea unei parole, afind n ecou caracterul *.
radio prezint un set de butoane radio, din care se poate selecta doar o variant. Dac este prezent
atributul Checked, atunci alternativa va fi selectat implicit.
checkbox permite selectarea multipl la mai multe opiuni.
image permite selectarea unui punct dintr-o imagine. La selectare se trimit automat (ca i la tipul
submit) perechile nume/valoare spre CGI. In ce privete poziia selectat din imagine, se
furnizeaz dou perechi nume.x=x nume.y=y, indicndu-se coordonatele, n pixeli, ale punctului
selectat din imagine.
hidden specific o valoare setat de formular fr ca utilizatorul s dea vre-un input.
submit trimite perechile de informaii ctre CGI.
reset reseteaz valorile formularului la valorile specificate implicit.
Name indic numele cmpului, nume care va fi transmis spre CGI ca prim component n
perechile nume/valoare.
Value fixeaz o valoare implicit pentru cmp. Checked fixeaz o alegere implicit pentru o
alternativ radio.
Src indic URL-ul atunci cnd avem Type=image.
Text indic faptul c este vorba de o singur linie text de intrare. La ENTER, se face automat
submit.
Size indic dimensiunea afiat pentru intrarea de tip text. Maxlength fixeaz limita maxim a
acestei lungimi.
Tagul <TEXTAREA are sintaxa:
<TEXTAREA

Name="string"

Rows="n"

Cols="n" >

Specific o intrare text pe mai multe linii. Prin Rows i Cols se specific numrul de linii i de
coloane care dimensioneaz aceast zon de text.
Ca i <INPUT i <TEXTAREA, tagul <SELECT este utilizat pentru a prelua informaii de la
utilizator. n inteiorul unui tag <SELECT pot s apar mai multe taguri <OPTIONS. Dintre
opiunile selectate se poate alege una i numai una dintre ele. Sintaxa celor dou taguri este:
<SELECT Name="string"
<OPTION Selected
<OPTION Selected
. . .
</SELECT>

Size="n" Multiple >


Value="n" >
Value="n" >

SO2 - Comunicatii si SO distribuite

35

Name este numele atribuit cmpului select. Size indic numrul de elemente vizibile la un
moment dat dintre toate opiunile posibile. Multiple permite selectarea mai multor valori dintre
opiunile oferite.
Selected indic o opiune selectat n mod implicit. Value indic ce valoare va fi trimis spre
CGI n cazul selectrii.

5.2 CGI i comunicaii prin URLConnection


5.2.1 Tehnologia CGI
Tehnologia CGI, acronim de la Common Gateway Interface este una din cele mai vechi interfae standard de
comunicare dintre o aplicaie program i un client Web, prin intermediul unui server Web. Astfel, serverul
Web transmite cererea clientului, aplicaiei respective. Aceasta proceseaz cererea i transmite rezultatul
napoi la serverul Web, care la rndul su, forwardeaz rspunsul la clientul care a lansat cererea.
Cnd utilizatorul solicit o pagin Web, serverul, ca rspuns, i trimite napoi pagina respectiv. Dar dac
utilizatorul completeaz un formular html, serverul transmite informaiile primite unui program CGI, care le
proceseaz, dup care trimite napoi la server un mesaj de confirmare. Un document HTML este un fiier
text static, care i pstreaz o stare constant. Pe de alt parte, un program CGI este executat n timp real i
genereaz n mod dinamic, un document HTML.
Un program CGI poate fi scris ntr-o diversitate de limbaje de programare, cele mai populare fiind: C, C++,
Java, Perl, Unix shell,Visual Basic, AppleScript.
Aplicaia distribuit este format din trei nivele (aa numit arhitectur three-tier):
1. Nivelul client, care furnizeaz, rnd pe rnd, ctre nivelul urmtor serverul Web -, una sau mai
multe linii de text care urmeaz a fi transformate.
2. Nivelul server Web, aflat n general pe o alt main dect clientul. Acesta preia liniile furnizate de
client, le transmite nivelului CGI, acesta le va transforma, le va ntoarce spre serverul Web, care la
rndul lui le va comunica transformate clientului.
3. Nivelul CGI care execut efectiv transformarea liniilor de text.
Pentru descrierea plicaiei, programatorul trebuie s implementeze numai clientul i CGI. Drept server Web
l vom folosi pe cel de pe maina linux.scs.ubbcluj.ro.

5.3 Construcia unui contor de pagini Web


Pentru construirea unui counter, folosim un program CGI i un applet care s comunice cu acesta. CGI-ul i
ntreine un fiier binar de 4 octei care numrul ultimei consulri a unei anumite pagini. Numele acestui
fiier este obinut din URL-ul CGI-ului, din care se pstreaz doar literele i cifrele numelui de CGI, iar
toate literele mari sunt transformate n litere mici; la acest nume se mai adaug sufixul ".count". De
exemplu, dac URL-ul este:
http://www.cs.ubbcluj.ro/~florin/cgi-bin/counterCGI.cgi
atunci fiierul ntreinut de CGI are numele:

SO2 - Comunicatii si SO distribuite

36

countercgicgi.count

5.3.1 Iniializarea fiierului contor


Programul 7.15 iniializeaz astfel de fiiere, prelund de la intrarea standard numele fiierului i valoarea
iniial:
#include <stdio.h>
#include <fcntl.h>
main (int c, char *a[]) {
int i, f;
if (c != 3) {
printf("Apel: counterInit numeFisier valoareInitialaContor");
exit(1);
}
f = open(a[1], O_CREAT|O_WRONLY|O_TRUNC, 0666);
i = atoi(a[2]);
write(f, &i, sizeof(int));
close(f);
}

Programul 5.1 Sursa de iniializare contor


Pentru a putea fi apelat de ctre CGI, acest fiier trebuie s aib cel puin drepturile 0666!

5.3.2 Programul CGI


Acesta primete de la intrarea standard numele fiierului. Apoi l deschide, citete valoarea curent, o
incrementeaz, o rescrie la loc i nchide fiierul. Dup aceea trimite napoi rspunsul ctre apelatorul CGIului, n conformitate cu protocolul HTTP pentru transmiterea de text simplu. Rspunsul const dintr-o linie
(de maximum 10 caractere) care conine numai cifrele zecimale ce reprezint valoarea curent a contorului.
Textul surs al CGI este prezentat n programul 7.16.
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
extern int errno;
main (int c, char *a[]) {
int i=-1, f;
char s[256];
fgets(s, 256, stdin);
// Citeste numele fisierului
f = open(s, O_RDWR);
// Deschide fisierul
if (f > 0) {
lockf(f, F_LOCK, 0);
// Blocheaza fisierul pentru incrementare
read(f, &i, sizeof(int)); // Citeste numarul
i++;
// Incrementeaza
lseek(f, 0, 0);
// Repozitioneaza la inceput
write(f, &i, sizeof(int)); // Rescrie noul numar
lockf(f, F_ULOCK, 0);
// Deblocheaza fisierul
close(f);
// Inchide fisierul
}
else
perror("");
printf("Content-type: text/plain\n\n%d\n", i); // Trimite numarul la client
}

Programul 5.2 Sursa counterCGI.c

SO2 - Comunicatii si SO distribuite

37

Pentru cazul nostru, acest fiier executabil va fi fiierul:


~/public_html/cgi-bin/counterCGI.cgi

6 Socket: utilizare din C sub Unix i din C++ sub Windows


6.1 Noiunea de socket
Un socket este un capt de comunicaie sau punct final de comunicaie, care poate fi numit i adresat
ntr-o reea. Este locul unde programul de aplicaie se ntlnete cu furnizorul mediului de transport. Din
perspectiva unui program de aplicaie, un socket este o resurs alocat de sistemul de operare. Din punctul
de vedere al unui sistem de operare, este o structur de date ntreinut de ctre nucleul sistemului de
operare. Aceast structur este referit n programele de aplicaie printr-un ntreg numit descriptor de
socket.
Dou aplicaii pot comunica ntre ele prin socket doar dup ce fiecreia dintre ele sistemul de operare i-a
alocat un socket. Exist un numr de descriptori de socket rezervai pentru aplicaiile de sistem, restul
descriptorilor fiind disponibili pentru utilizatori.
nterfaa socket ascunde utilizatorului detaliile reelei fizice, ea este caracterizat numai prin serviciile pe
care le asigur. Comunicaia prin socket este parte integrant a nivelului sesiune din cadrul modelului OSI.
In prezent, mecanismul socket este operaional pe toate sistemele de operare de tip Unix: SunOS, Solaris,
SCO, LINUX etc. Incepnd cu 1990, au aprut pachete care permit utilizarea acestui mecanism i sub toate
variantele Microsoft WINDOWS: 3.1, 3.11, 95, NT. Mai mult, dup cum se va vedea n cele ce urmeaz,
ntre cele dou clase de sisteme de operare compatibilitatea este perfect.

6.2 Tipuri de socket


Din punctul de vedere al transportului efectuat, se disting dou tipuri de socket: socket stream i socket
datagram. Comunicarea este posibil numai dac la ambele capete este utilizat acelai tip de socket!
Socket stream
nterfaa socket stream definete un serviciu orientat conexiune. Datele sunt transmise fr erori i fr
duplicri. Ele sunt recepionate n aceeai ordine n care au fost transmise. Fluxul de date prin reea este
realizat astfel nct s se evite depirea unei valori maxime de octei la un moment dat. Nu se impun nici un
fel de limitri asupra datelor, acestea considerndu-se simple iruri de octei.
Prin analogie cu comunicaia cotidian, un socket stream este analog cu un aparat telefonic, la care a)
proprietarul formeaz un numr i dup stabilirea legturii ncepe s discute cu persoana de la cellalt capt
al firului; b) aparatul plus ntreaga reea telefonic asigur stabilirea legturii i asigur stabilitatea acesteia
pn la nchiderea unuia dintre cele dou aparate.
Pentru socket stream transportul este realizat folosind protocolul TCP. Fiind vorba de serviciu orientat
conexiune, este potrivit analogia cu aparatul telefonic. Unul din protocoalele nivelului aplicaie, i anume
File Transfer Protocol (FTP), folosete serviciile oferite de socket stream.

SO2 - Comunicatii si SO distribuite

38

Socket datagram
Interfaa socket datagram definete un serviciu fr conexiune n care datagramele sunt transmise ca i
pachete separate. Acest serviciul nu asigur garanii ale recepionrii datelor, care pot fi pierdute ori
duplicate, iar datagramele pot ajunge n alt ordine dect cea n care au fost transmise. Mrimea unei
datagrame este limitat de numrul de octei care pot fi transmii ntr-o singur tranzacie. Nu se realizeaz
nici o dezasamblare i reasamblare a pachetelor.
Prin analogie cu comunicaia cotidian, un socket datagram poate fi asemnat cu o cutie potal n care: a)
proprietarul ei (programul de aplicaie) depune corespondena de trimis i de unde i ridic corespondena
trimis; b) factorul potal (furnizorul mediului de transport) deschide cutia de cteva ori pe zi, ridic
corespondena de expediat i depune corespondena sosit la adresa respectiv.
Pentru socket datagram transportul este realizat folosind protocolul UDP. Analogia cu cutia potal este
potrivit acestui tip de socket. Dintre protocoalele nivelului aplicaie, TFTP i NFS se bazeaz pe un astfel
de socket.
Repere pentru alegerea tipului de socket
n vederea alegerii unui anumit tip de socket trebuie luate n considerare mai multe aspecte. Primul dintre
acestea este c realizarea unei comunicaii cu o aplicaie existent impune folosirea aceluiai protocol ca i
aplicaia respectiv. De exemplu, dac aplicaia n cauz folosete protocolul TCP, atunci se va utiliza
socket stream.
Un alt aspect va fi cel legat de sigurana i eficiena comunicaiei. Socket stream asigur o conexiune sigur,
acest lucru realizndu-se ns cu o minim reducere a performanei, deoarece sunt necesare eforturi de
calcul suplimentare pentru meninerea conexiunii i verificrile de corectitudine. Din fericire, la nivel
utilizator acest lucru nu se observ. Socket datagram este relativ nesigur deoarece pachetele pot fi ignorate,
alterate sau duplicate n timpul transmisiei. Se poate utiliza astfel de socket dac aplicaia implementeaz ea
nsi un mecanism propriu de corectitudine, sau dac aplicaia nu este prea sensibil la transmisii eronate.
Ctigul const n viteza de prelucrare, sporit n raport cu cea de la socket stream.
Cantitatea de date care se transfer este nc un indiciu de alegere: pentru cantiti mari de date se vor utiliza
socket stream.
In fine, dac comunicaia se desfoar ntr-o reea LAN, atunci de cele mai multe ori socket datagram este
suficient. Pentru reele WAN este mai recomandabil folosirea socket stream.

6.3 Mecanismul de socket n limbajul C


Intregul mecanism socket este disponibil, indiferent de platform, prin intermediul unor tipuri de date i a
unor funcii apelabile din limbajul C, eventual din limbajul C++. Evident, aceast soluie asigur un grad
foarte nalt de portabilitate, deoarece aceste limbaje sunt astzi cele mai rspndite, fie c este vorba de
platforme de tip Unix, fie c este vorba de platforme Microsoft WINDOWS. Evident, celelalte platforme
existente astzi n lume sunt aliniate la una dintre aceste dou platforme.
Din raiuni de portabilitate, constantele folosite drept parametri pentru socket sunt numere ntregi.
Structurile de date folosite sunt definite prin typedef n aceste fiiere header i respect sintaxa limbajului C.
Din pcate, exist unele mici deosebiri, dar din fericire ele se refer numai la numele fiierelor header
folosite, care pot s difere de la o platform la alta.
Astfel, succesiunea citrilor de headere de sub Unix:

SO2 - Comunicatii si SO distribuite

39

#include <netinet/in.h>
#include <sys/socket.h>
#include <netdb.h>

au fost nlocuite n pachetul WINSOCK printr-o singur citare:


#include <winsock.h>

In continuare vom cita headerele folosite sub Unix, urmnd ca acolo unde este cazul (mai ales la aplicaii) s
indicm alternativele.
Tipurile de date folosite n sistemul Unix se gsesc n headerul <sys/types.h>, motiv pentru care practic
acest header trebuie citat n fiecare program.

6.3.1 Adrese socket


Inainte de a detalia utilizarea socket, trebuie s indicm modalitatea prin care dou procese deprtate pot s
ia legtura. Pentru realizarea unei astfel de comunicaii este necesar existena unui cvintuplu:
{Protocol,AdresaLocala,ProcesLocal,AdresaDepartata,ProcesDepartat}

Pentru a-i pstra independena de platform, socket permite utilizarea mai multor familii de adrese. O
familie de adrese definete un stil de adresare. Toate hosturile care sunt n aceeai familie de adrese neleg
i folosesc aceeai schem pentru adresarea capetelor socketului. Familiile de adrese sunt identificate prin
numere ntregi. Numele acestora ncepe cu AF (Adress Family).
Cea mai important familie de adrese este AF_INET, familie ce definete adresarea n domeniul Internet. Pe
lng acest tip de familie, sistemul Unix recunoate i alte tipuri, cum ar fi AF_UNIX care reprezint
sistemul local (protocoale interne Unix), AF_NS pentru protocoale XEROX NS, AF_IMPLINK pentru IMP
(Interface Message Procesor).
Generic, structura unei adrese socket este urmtoarea:
struct sockaddr {
u_short
sa_family;
char
sa_data[14];
}

/* valoare AF_xxx */
/* dependent de familie */

i ea este definit n <sys/socket.h> .


Cmpul sa_family indic familia de adrese folosit.
Coninutul celor 14 octei ai cmpulului sa_data este interpretat n funcie de familia de adrese folosit. De
fapt, dup cum vom vedea, unele familii folosesc chiar mai mult de 14 octei n acest scop.
Fiecare familie de adrese are definit structura proprie de adres, structur care se suprapune peste cea
generic n momentul transmiterii ei ctre nucleu. S ne oprim pentru moment la dou familii de adrese:
AF_INET i AF_UNIX.
Adresele din familia AF_INET sunt de tip struct sockaddr_in i sunt definite n <netinet/in.h> astfel:
struct in_addr {
u_long
s_addr;
}

/* pe 32 biti o adresa IP */

SO2 - Comunicatii si SO distribuite


struct sockaddr_in {
short
u_short
struct in_addr
char s
}

40

sin_family;
sin_port;
sin_addr;
in_zero[8];

* valoarea AF_INET */
/* numarul de port */
/* adresa IP */
/* nefolosit */

De remarcat faptul c structura sockaddr_in include n interiorul ei structura in_addr.


Adresele din familia AF_UNIX sunt de tip struct sockaddr_un i sunt definite n <sys/un.h> astfel:
struct sockaddr_un {
short
sun_family;
char
sun_path[108];
}

/* AF_UNIX */
/* cale spre fisier Unix*/

Trebuie remarcat c ambele structuri de adrese (ca i structurile celorlalte familii) ncep cu numrul
indicator de familie. Deci, schimbnd indicatorul de familie aceeai zon de memorie poate fi interpretat ca
un alt tip de adres, aa cum se vede n fig. 1.1

struct sockaddr_in

struct sockaddr_un

Familia AF_INET

Familia AF_UNIX

Port, 2 octeti

Nume de cale,
maximum 108 octeti

Adres IP, 4 octeti


Spatiu nefolosit

Figura 6.1 Suprapunerea a dou adrese socket

6.4 Scheme cadru de implementri client / server


Programarea aplicaiilor care folosesc socket urmeaz nite scenarii bine stabilite. Este vorba de ordinea de
apelare a funciilor sistem n funcie de tipul de socket i de faptul c un program este pe post de server sau
pe post de client. (De multe ori, mai ales atunci cnd se folosete socket datagram, dispare nelesul clasic de
client i de server).

6.4.1 Scenariul aplicaiilor socket stream


Pentru aplicaiile care folosesc protocol cu servicii orientate conexiune, deci socket stream, se folosesc
cteva apeluri sistem Unele dintre ele sunt apelate de ctre server, altele de ctre client. Succesiunea
acestora este dat n fig. 1.2

SO2 - Comunicatii si SO distribuite

41

Figura 6.2 Scenariul aplicaiilor socket stream


Vom prezenta acum pe scurt rolul acestora, urmnd s descriem complet fiecare dintre apelurile sistem ntro seciune urmtoare.
Att serverul, ct i clientul au cte o parte de iniializare dup care urmeaz descrierile aciunilor curente.
Partea de iniializare a serverului
socket cere nucleului sistemului s creeze un socket prin care s poat fi contactat de ctre clieni. Aici se

fixeaz familia de adrese folosit, precum i tipul de socket folosit: stream sau datagram.
bind transmite nucleului numrul de port la care serverul ateapt s fie contactat. precum i faptul c poate
fi contactat prin orice interfa de reea de pe maina server.
listen cere nucleului s dimensioneze lungimea cozii de ateptare la socket.
Partea de iniializare client
socket cere nucleului sistemului s creeze un socket prin care s poat contacta de ctre clieni. Aici se

fixeaz familia de adrese folosit, precum i tipul de socket folosit: stream sau datagram.
Relaia curent ntre un client i un server
La un moment dat clientul execut un apel sistem connect, prin care i transmite nucleului lui adresa IP i
numrul de port ale serverului cruia dorete s-i cear un serviciu. Nucleul, prin mecanismul socket
contacteaz serverul solicitat.
Serverul, odat cu lansarea apelului sistem accept, rmne n ateptare pn cnd un client l contacteaz.
Odat contactat, el primete adresa IP i numrul de port ale clientului care l-a contactat.
Clientul execut un apel sistem send (sau mai multe) prin care transmite serverului un mesaj prin care i
cere un serviciu. Serverul, prin apelul (apelurile) sistem recv recepioneaz acest mesaj.
Apoi, Serverul execut aciunile necesare satisfacerii cererii clientului.
Trimiterea rezultatului de ctre server ctre client se face similar: serverul trimite prin apeluri send, iar
clientul recepioneaz prin apeluri recv.

SO2 - Comunicatii si SO distribuite

42

In seciunile care urmeaz vom descrie pe larg apelurile sistem i vom da exemple de folosire a lor n
aplicaii.
Trebuie precizat (detaliile mai trziu) c apelurile sistem send i recv se comport ca i funcii Unix care
execut operaii de intrare/ieire obinuite; printre argumente nu mai apar adrese IP, nici numere de porturi.
Ele sunt fixate n momentul contactrii connect - accept.

6.4.2 Scenariul aplicaiilor socket datagram


La fel ca n seciunea precedent, vom prezenta acum pe scurt rolul acestora, urmnd s descriem complet
fiecare dintre apelurile sistem ntr-o seciune urmtoare. Succesiunea acestora este ilustrat n fig. 3.
SERVER

CLIENT

socket

socket

bind

bind

Blocheaz pn la o cerere a unui client


recvfrom
Date pentru

sendto

Actiunile necesare servirii cererii


sendto

Datele de rspuns

recvfrom

Figura 6.3 Scenariul aplicaiilor socket datagram


Prile de iniializare ale serverului i ale clientului
socket cere nucleului sistemului s creeze un socket prin care s poat comunica cu partenerii. Aici se

fixeaz familia de adrese folosit, precum i tipul de socket folosit: stream sau datagram.
bind transmite nucleului numrul de port prin care se va comunica.
Relaia curent ntre un client i un server
La un moment dat clientul execut un apel sistem sendto, prin care i transmite nucleului lui adresa IP i
numrul de port ale serverului cruia dorete s-i cear un serviciu, precum i mesajul prin care i cere
serverului un serviciu. Nucleul, prin mecanismul socket contacteaz serverul solicitat i-i transmite mesajul.
In cazul n care cererea este compus din mai multe mesaje, ele sunt trimise succesiv prin apeluri
independente.
Serverul, odat cu lansarea apelului sistem recvfrom, rmne n ateptare pn cnd un client l
contacteaz. Odat contactat, el primete adresa IP, numrul de port ale clientului care l-a contactat precum
i mesajul prin care i se cere un serviciu.
Apoi, Serverul execut aciunile necesare satisfacerii cererii clientului.
Trimiterea rezultatului de ctre server ctre client se face similar: serverul trimite prin apeluri sendto, iar
clientul recepioneaz prin apeluri recvfrom, eventual prin mesaje succesive, fiecare dintre ele purtnd
adresele IP de contact i numerele de port.

SO2 - Comunicatii si SO distribuite

43

In seciunile care urmeaz vom descrie pe larg apelurile sistem i vom da exemple de folosire a lor n
aplicaii.

6.5 Biblioteca de apeluri sistem socket


6.5.1 Apeluri socket de conexiune
Sintaxele apelurilor: socket, bind, listen, connect, accept
Prototipurile acestor apeluri sistem sunt date mai jos. Pentru simplificarea prezentrii rolurilor acestora,
acelai parametru a fost notat cu acelai nume n toate prototipurile de apeluri.
Aceste apeluri sistem trebuie precedate de specificarea fiierelor header:
# include <sys/types.h>
# include <sys/socket.h>

Prototipurile de apel sunt:


int

socket ( int familie, int tip, int protocol );

int

bind

int

listen ( int sd, int lungcoada );


/*intoarce 0 la succes, -1 la eroare */

int

connect( int sd, struct sockaddr *departe, int *lungdeparte);


/*intoarce 0 la succes, -1 la eroare */

int

accept ( int sd, struct sockaddr *departe, int *lungdeparte);

( int sd, struct sockaddr *local, int lunglocal );


/*intoarce 0 la succes, -1 la eroare */

In caz de eec (parametri eronai, conectare imposibil etc.) sunt semnalate prin ntoarcerea unei valori
negative. Pentru detalierea tipului de eroare, trebuie s fie citat headerul:
# include <errno.h>

i variabila:
extern

int

errno;

Parametrul sd care apare la ultimele patru apeluri este descriptorul de socket, valoare care este ntoars de
ctre apelul sistem socket.
Parametrii local i departe reprezint pointeri ctre adrese de socket, care sunt structuri de tipul celor
descrise n anterior. Asociai acestora, parametrii lunglocal i lungdeparte sunt ntregi sau pointeri la
ntregi care indic lungimea de reprezentare a acestor adrese.
In continuare, prezentm pe rnd fiecare dintre cele cinci apeluri sistem.
Exemplele lor de utilizare vor fi n concordan cu schemele din fig. 1, 2 i vor fi date n aplicaiile
prezentate n acest capitol.

SO2 - Comunicatii si SO distribuite

44

Apelul sistem socket


Acest apel sistem creaz un socket care va asigura conectivitatea programului local, fie el server sau client.
Apelul ntoarce un ntreg, notat n cele ce urmeaz cu sd, care reprezint descriptorul de socket. Apelurile
sistem care urmeaz folosesc acest descriptor ca i parametru.
Parametrul familie indic familia de adres socket utilizat. Printre altele, valoarea ei poate fi AF_INET,
AF_UNIX etc. Se pot folosi i constantele echivalente PF_INET, PT_UNIX etc. Pentru restul acestei lucrri
vom folosi numai constanta AF_INET.
Parametrul tip indic tipul de socket folosit. Pentru socket stream acesta are ca valoare constanta
SOCK_STREAM, iar pentru socket datagram constanta SOCK_DGRAM. Mai exist i alte valori posibile, dar
pentru acestea nu sunt admise toate combinaiile familie - tip.
Parametrul protocol este un argument care are valoarea 0, cu semnificaia lsm sistemului alegerea
protocolului. Exist ns, aplicaii specializate unde se cere specificarea. De exemplu, pentru familie ==
AF_INET sunt posibile combinaiile:
tip
SOCK_STREAM
SOCK_DGRAM

Protocol
IPPROTO_TCP
IPPROTO_UDP

Protocol implicit
TCP
UDP

Constantele de protocol sunt definite n <netinet/in.h>.


Apelul sistem bind
Acest apel sistem se utilizeaz n mai multe contexte:
1. Serverul i nregistreaz adresa socket proprie local, pentru socketul sd; lungimea adresei
local este lunglocal. In local trebuie trecut, spre a fi transmis nucleului, numrul de port la care poate fi
contactat. Acesta poate fi un numr de port rezervat sau un numr la dispoziia utilizatorului). Tot n local,
n cmpul sin_addr.s_addr se poate trece fie adresa IP a mainii server, fie, de cele mai multe ori,
constanta INADDR_ANY cu semnificaia: pot fi contactat pe orice interfa de reea de pe maina pe care
lucrez.
2. Un client legat prin socket datagram sd indic nucleului, prin local de lungime lunglocal,
numrul de port i adresa IP la care poate fi contactat. La aceast adres unic i vor rspunde toate serverele
pe care le va contacta pe socket sd.
Apelul sistem listen
Precizeaz numrul maxim lungcoada de conexiuni care sunt acceptate pe socket sd s atepte dac
serverul este ocupat. Dac sosesc mai multe, cele ce depesc lungcoada vor fi refuzate.
Majoritatea sistemelor de operare nu admit mai mult de cinci clieni simultan.
Apelul sistem connect
Un proces client care folosete socket stream sd, solicit nucleul propriu s conecteze, prin sd, serverul
avnd adresa socket departe reprezentat pe lungdeparte octei.
Acest apel sistem stabilete pentru client patru din cele cinci elemente ale conexiunii, protocolul fiind
stabilit anterior. La cele mai multe protocoale, connect ntoarce rezultatul abia dup stabilirea conexiunii.

SO2 - Comunicatii si SO distribuite

45

Apelul este folosit la legtura de tip conectare. Se poate folosi i pentru legturi fr conectare, pentru a
obine adresa serverului.
Adresa IP a clientului este cunoscut i pus de ctre nucleul lui, care atribuie, n mod temporar pe durata
conexiunii, a unui numr de port.
Apelul sistem accept
Acest apel sistem pune serverul care ateapt o conexiune socket stream sd. Serverul rmne n ateptare
pn cnd un client reuete un connect la el. In momentul realizrii conexiunii, n argumentele departe i
lungdeparte sunt ntoarse adresa socket a clientului i lungimea pe care se reprezint aceast adres.
Apelul sistem ntoarce trei valori:
1. Un ntreg pe care-l vom nota fd. Acesta reprezint un nou descriptor, pe care serverul l folosete pe post
de descriptor de fiier pentru schimbul de mesaje cu clientul.
2. Adresa socket a procesului client n departe.
3. Lungimea de reprezentare a acestei adrese n lungdeparte.
Descriptorul fd ntors de accept se comport ca un descriptor de fiier i numai prin el serverul manevreaz
mesajele n ambele sensuri. Pentru o distincie mai clar, se folosesc termenii de socket (descriptor) de
ntlnire pentru sd i socket (descriptor) de schimb pentru fd.

6.5.2 Particulariti socket Windows


In continuare, precizm cteva particulariti de utilizare a bibliotecii WINSOCK sub Windows.
Pentru portarea Unix -> WINDOWS a unui program care comunic prin socket sunt necesari i obligatorii
urmtorii doi pai:
1. Se vor nlocui liniile cu citarea fiierelor header citate mai sus. Deci:
#
#
#
#

include
include
include
include

<netinet/in.h>
<fcntl.h>
< sys/socket.h>
<netb.h>

se va nlocui cu:
# include <winsock.h>

2. Orice aplicaie WINDOWS care folosete WINSOCK trebuie s iniializeze biblioteca socket. Aceasta se
realizeaz declarnd trei variabile i apelnd dou funcii. Apelurile trebuie s fie primele instruciuni n
cadrul funciei main a programului. Secvena de iniializare este:
WORD wVersiune;
WSADATA
wDate;
int
wEroare;
wVersiune = MAKEWORD(1,1);
/* Se cere versiunea 1.1 */
wEroare = WSAStartup( wVersiune, &wDate); /* Initbiblioteca */

Incepnd cu WINDOWS 95 se pot genera aplicaii consol la care s fie legat biblioteca pe 32 de bii
wsock32.lib. Sub Visual C++ 4.2, opiunea de includere se afl n ierarhia de meniuri
Build/Settings/Link.

SO2 - Comunicatii si SO distribuite

46

6.5.3 Operaii de I/O prin socket


Apelurile sistem send, recv, sendto, recvfrom
Acestea sistem sunt cele mai simple apeluri sistem prin intermediul crora se pot face schimburi de date
ntre client i server prin socket. Utilizarea lor presupune citarea fiierelor header <sys/types.h> i
<sys/socket.h>. Sintaxele acestor apeluri sunt:
int
int
int
int

send
(int
sendto (int
recv
(int
recvfrom(int

sd,char
sd,char
sd,char
sd,char

*T,int
*T,int
*T,int
*T,int

n,int
n,int
n,int
n,int

f );
f,struct sockaddr *D,int lD);
f);
f,struct sockaddr *E,int *lE);

Parametrul sd este descriptorul de socket prin care se realizeaz comunicaia cu partenerul deprtat. Acest
ntreg provine, aa cum am vzut, dintr-un apel socket, cu excepia cazului send i recv dintr-un server
socket stream, cnd acesta provine din apelul unui accept.
Apelurile send i sendto expediaz prin sd un numr de maximum n octei pe care-i ia din memoria intern
ncepnd cu adresa T. Programatorul trebuie s depun n zona tampon de adres T aceti n octei. In cazul
send, fiind vorba de socket stream, adresa IP i portul destinatarului se stabilete la conexiune. In cazul
sendto, programatorul trebuie s depun n prealabil adresa IP i numrul de port al partenerului destinatar
n zona punctat de D pe o lungime de lD octei. De multe ori, adresa IP i portul destinatarului se gsesc
deja n zona D dac aceeai zon este folosit i la apelul pereche precedent.
Intregul ntors de cele dou apeluri reprezint numrul de octei care s-a putut transmite. In caz de eroare se
ntoarce o valoare negativ.
Apelurile recv i recvfrom recepioneaz prin sd un numr de maximum n octei pe care-i depune n
memoria intern ncepnd cu adresa T. Programatorul trebuie s se asigure c zona tampon are rezervai la
adresa T cel puin n octei. In cazul recv, fiind vorba de socket stream, adresa IP i portul destinatarului se
stabilete la conexiune. In cazul recvfrom, programatorul primete adresa IP i numrul de port al
partenerului destinatar n zona punctat de D i lungimea ei de reprezentare la adresa lD.
Intregul ntors de cele dou apeluri reprezint numrul de octei care au fost recepionai. Faptul c s-a
nchis conexiunea este semnalat prin ntoarcerea valorii zero. In caz de eroare se ntoarce o valoare negativ.
Argumentul f este un flag care are de regul valoarea 0, lsnd astfel pe seama sistemului fixarea unor
flaguri. Este posibil totui ca el s fie compus din reuniunea (OR) a unora din constantele:
MSG_OOB pentru a emite sau recepiona cu bufferizare;
MSG_PEEK pentru a bloca mesajele pn la recepia complet a celui curent;
MSG_DONTROUTE nu se ruteaz mesajul ntre reele.
Observaie: tratarea situaiilor n care nu s-au transmis sau recepionat exact cei n octei solicitai cade
exclusiv n sarcina progrramatorului! Dac prin socket se poate transmite fie i numai un octet, acesta se va
transmite i operaia este considerat ncheiat! Un remediu posibil este, de exemplu, funciile Send i Recv.
Comparaii cu apelurile read i write
Putem compara operaiile de I/O clasice cu fiiere i operaiile I/O prin socket prezentate mai sus. Pentru
fiiere exist apelurile sistem open, create, close, read, write. Versiunea iniial a TCP/IP din 1981 folosea
aceste funcii. S-a constatat ns c nu sunt suficient de bune pentru comunicaia n reele. Iat cteva dintre
motive.

SO2 - Comunicatii si SO distribuite

47

1.
Relaia client-server nu este simetric. O conectare n reea cere programului s tie ce rol (client sau
server) joac.
2.
Conectarea n reea poate fi bazat pe conexiune sau fr conexiune. Relaia open-close este
orientat spre conexiune, n timp ce relaia fr conexiune nu are echivalent.
3.
Spre deosebire de fiiere, n reele numele este esenial. Pentru fiiere este suficient transmiterea
unui numr - descriptor de fiiere. Pentru comunicaii este esenial numele perechii pentru a verifica
autoritile de acces.
4.
Parametrii fiierelor sunt mult mai puini dect cei ce se transmit prin reea. Astfel, pentru reea este
necesar asocierea celor cinci componente cunoscute:
(protocol,adresalocala,portlocal,adresadepartata,portdepartat)

asociere care nu-i gsete echivalent la operaiile I/O cu fiiere.


5.
Pentru unele protocoale de comunicaie este semnificativ dimensiunea limitat a nregistrrilor.
Pentru I/O, aspectul este acela al fluxului de octei.
6.
Interfeele de reea trebuie s suporte mai multe protocoale de comunicaie.
Apelurile sistem sendmsg i recvmsg
Apelurile sistem I/O mai sus amintite nu asigur faptul c toi octeii solicitai vor fi transferai. Pentru a se
asigura aceast cerin prin operaii atomice, sunt folosite aceste dou apeluri sistem. Ele sunt descrise n
headerele <sys/types.h> i <sys/socket.h> i au prototipurile:
int sendmsg ( int sd, struct msghdr msg, int f );
int recvmsg ( int sd, struct msghdr msg, int f );

Semnificaia parametrilor sd i f coincide cu cea a apelurilor sistem precedente. Structura msghdr este:
struct
msghdr {
caddr_t
msg_name;
int
msg_namelen;
struct
iove
*msg_iov;
int msg_iovlen;
caddr_t
msg_accrights;
int
msg_accrightslen;
}

/*Adresa opional*/
/* lungime adres*/
/* bucile de memorie */
/* cte bucati sunt */
/* drepturi de acces schimb */
/* lungine zona de drepturi */

Primele dou cmpuri sunt folosite de ctre recvfrom i sendto, pentru lucrul n mod neconexiune. Pentru
conexiune se pune NULL. Ultimele dou elemente sunt folosite pentru drepturile de acces ntre procese.
Rutine de conversii ale octeilor i ntregilor
Aceste rutine asigur ordonarea octeilor din reprezentarea unui ntreg n concordan cu arhitecturile i
protocoalele cu care se lucreaz. De regul, ntregii scuri sunt reprezentai pe 16 bii, iar cei lungi pe 32 bii.
Implementrile depind de main i sunt de una dintre categoriile: big endian sau little endian.. In capitolul
urmtor, dedicat RPC, vom detalia aceast problem.
La nivelul comunicaiilor prin socket, ntregii sunt tratai ca fiind fr semn. Este definit o reprezentare
universal a lor, numit reprezentare de reea. Folosind fiierele header <sys/types.h> i
<netinet/in.h>, conversia ntregilor ntre reprezentarea de reea se face cu ajutorul urmtoarelor patru
funcii.
u_long htonl( u_long I );
u_short htons( u_short I );

/* host to network long */


/* host to network short */

SO2 - Comunicatii si SO distribuite


u_long ntohl( u_long I );
u_short ntohs( u_short I );

48
/* network to host long */
/* network to host short */

Funciile transform argumentul I i ntorc ntregul convertit, astfel:


Funcia htonl convertete un ntregul lung de reea I ntr-un ntreg lung local.
Funcia htons convertete un scurt lung de reea I ntr-un ntreg scurt local.
Funcia ntohl convertete un ntreg lung local I ntr-un ntreg lung de reea.
Funcia ntohs convertete un ntreg lung local I ntr-un ntreg lung de reea.
Rutine de manevrare a irurilor de octei
Frecvent sunt necesare o serie de operaii asupra octeilor, privite ca iruri de octei ce nu se supun
ntotdeauna regulilor limbajului C. Aceste funcii fac parte din pachetul de rutine standard C. Deoarece
patru dintre ele sunt destul de des folosite n exemplele care urmeaz, le prezentm pe scurt.
memcpy(char *s, char *d, int n);
memset(char *d, int v, int n);
strcpy( char *d, char*s);
int strcmp(char *a, char *b);
memcpy copiaz n octei de la adresa s la adresa d. memset depune ncepnd cu adresa d, n octei cu coninut
identic, valoarea v. strcpy copiaz un ir de octei reprezentat ca n C, de la adresa s la adresa d. strcmp
compar irurile a i b, reprezentate ca n C i ntoarce o valoare negativ dac a < b, o valoare pozitiv
dac a > b i valoarea 0 dac a = b.

6.5.4 Gestiunea adreselor IP i Internet


Pentru conversia acestora sunt necesare headerele <sys/socket.h>, <netinet/in.h> i <arpa/inet.h>.
Rutinele inet_addr i inet_ntoa
Prototipurile acestor dou rutine sunt:
unsigned long inet_addr ( char *S );
char
*inet_ntoa
( struct in_addr I );

Rutina inet_addr transform irul de caractere S scris n convenie C i care conine o adres IP scris n
notaia punctual, ntr-o adres pe 32 bii a crei valoare o ntoarce.
Rutina inet_ntoa face operaia invers, adic transform ntregul lung I ntr-un ir de caractere care
conine adresa IP n notaia punctual.
S considerm, spre exemplu, secvena de mai jos, unde d este un pointer:
strcpy( d, inet_toa( (struct in_addr) inet_addr(193.226.40.34)))

Prin aceasta, la adresa d se va depune irul 193.226.40.34.

SO2 - Comunicatii si SO distribuite

49

Rutinele gethostname i gethostbyname


#include <unistd.h>
int gethostname(char *name, size_t len);

Funcia gethostname returneaz n parametrul de ieire name, de lungime maxim len, numele mainii
curente, pe care este conectat utilizatorul.
Adresele IP sunt mai dificil de manipulat de ctre utilizator i este de preferat s se foloseasc n locul lor
adresele Internet. Dup cum se poate ns vedea, rutinele socket lucreaz cu adrese IP.
Rutina gethostbyname ofer posibilitatea de a obine adresa IP echivalent cu o adres Internet.
Evident, pentru aceasta ea va provoca apelurile n lan ale DNS-urilor necesare obinerii acestei adrese.
Prototipul acestei rutine este:
struct hostent *gethostbyname(char *S);

S este irul, n convenie C care conine adresa Internet.


Structura hostent, ctre care rutina ntoarce un pointer, se definete astfel:
struct hostent {
char *h_name;
char **h_aliases;
int
h_addrtype;
int
h_length;
char **h_addr_list
}

/*
/*
/*
/*
/*

Numele oficial al hostului */


Lista de aliasuri */
Tipul adresei hostului */
Lungimea adresei */
lista de adrese IP date de DNS */

Aceast structur este destul de flexibil pentru a reine hosturi cu nume multiple i cu mai multe adrese IP.
Cmpul h_addr_list este un pointer la aceste adrese IP, scrise n notaia punctual.
In cazul cel mai simplu, i cel mai des folosit, se va prelua prima adres IP. Pentru a simplifica accesul la
aceasta, odat cu structura se definete i macroul:
#define

h_addr

h_addr_list[0]

In aproape toate exemplele care urmeaz determinarea adreselor IP se va face cu aceast rutin pornind de
la adrese Internet.

6.6 Exemple de aplicaii client / server cu socket


In aceast seciune vom prezentaun exemplu simplu de socket de tip stream, sub Unix.

6.6.1 rdir: Rezumat de director la distan


Prezentarea problemei
Se cere s se elaboreze o pereche de programe: client i server, ale cror roluri sunt urmtoarele.
Clientul primete ca parametri n linia de comand adresa Internet a serverului i numele unui director
despre care se presupune c se afl n sistemul de directori al serverului. Clientul contacteaz serverul, i
transmite acestuia numele de director i i cere ca rspuns rezumatul directorului.

SO2 - Comunicatii si SO distribuite

50

In ipoteza c directorul primit exist, serverul face rezumatul acestuia i trimite acest rezumat clientului
solicitant. Dac directorul nu exist, sau dac serverul nu are drepturi de acces la el, va ntoarce clientului
irul vid.
Clientul va afia pe ieirea standard rezumatul primit de la server.
In continuare prezentm implementarea acestei probleme, folosind socket-uri stream.
O variant rdir prin TCP
Implementm comunicaia prin socket de tip stream (orientat conexiune, utilizeaz nivelul de transport
TCP) i n consecin respectm ntocmai scenariul din fig. 2.
Varianta rdir, care ine cont de observaiile de mai sus, este compus din patru fiiere.
Programul 1.1 prezint o funcie, care primeste la intrare numele unui director i intoarce, prin acelasi
parametru, lista fisierelor din el.
#include <dirent.h>
/* Pentru Windows
#include <windows.h>
*/
int
read_dir (char *dir)
/* Primeste la intrare numele unui director si intoarce,
* prin acelasi parametru, lista fisierelor din el
*/
{

DIR *dirp;
struct dirent *d;
dirp = opendir (dir);
dir[0] = '\0';
if (dirp == NULL)
return (0);
while (d = readdir (dirp))
sprintf (dir, "%s%s\n", dir, d->d_name);
closedir (dirp);
/* Pentru Windows
WIN32_FIND_DATA d;
HANDLE hf;
BOOL b;

strcpy(director, dir);
strcat(director, "\\*.*");
dir[0] = '\0';
hf = FindFirstFile(director, &d);
b = hf != INVALID_HANDLE_VALUE;
while (b) {
sprintf (dir, "%s%s\n", dir, d.cFileName);
b = FindNextFile(hf, &d);
}
*/
return (sizeof (dir));
}

Programul 6.1 Sursa funciei read_dir.c


Al doilea fiier, programul 1.2, este un antet n care sunt definite constantele numr de port, lungimea
bufferului pentru rezumat i macroul de tratare a erorilor.

SO2 - Comunicatii si SO distribuite


#include
#include
#include
#include
#include
#include
#include
#include

51

<stdio.h>
<string.h>
<sys/types.h>
<sys/socket.h>
<netinet/in.h>
<netdb.h>
<signal.h>
<errno.h>

extern int errno; /*Indicatorul de erori ale apelurilor sistem


*/
#define ERR(S,N) {fprintf(stderr,"\n%d ",N);\
perror(S); exit(N);}
#define PORT_SERVER 12347
#define DIRSIZE 8192

Programul 6.2 Sursa fiierului header rd.h


In continuare, prin programele 1.3 i 1.4 sunt prezentate clientul i serverul. In acest exemplu, numele
mainii i directorul solicitat serverului sunt furnizate, de fiecare dat, la lansarea n execuie a fiecrui
client.
In al doilea rnd, adresa mainii server este furnizat printr-o adres IP. Aa cum am mai spus, sunt de
preferat adresele Internet. n consecin programul client trebuie s converteasc adresa Internet n adres
IP.
Al treilea aspect este cel al controlului corectitudinii apelurilor sistem. Se tie c toate funciile C ntorc cte
o valoare. Semnificaia valorilor ntoarse de apelurile sistem socket a fost deja prezentat. Dac n apelurile
sistem obinuite se mai permite citarea unui apel F pe post de instruciune:
F ( ) ;

n apelurile sistem de comunicaii, datorit probabilitii mai mari de apariie a unor situaii neobinuite /
erori, este indicat folosirea acestor apeluri n contextul:
if ( F ( ) )

n acest mod se va detecta mai uor apariia unei siuaii excepionale. n programele noastre, tratarea
acestora se face simplu: un macrou ERR d un mesaj pe ieirea standard, dup care programul se termin cu
un anumit cod de eroare.
Sursa aplicaiei client este dat n programul 1.3 (rdct.c).
#include <rd.h>
/* Pentru Windows
#include <winsock.h>
*/
main (int argc, char *argv)
{
char dir[DIRSIZE];
int sd;
struct sockaddr_in serv_addr;
struct hostent *hp;
/* Pentru Windows
WORD wVR;

SO2 - Comunicatii si SO distribuite

52

WSADATA wD;
int we;
wVR = MAKEWORD(1,1);
we = WSAStartup(wVR, &wD);
*/
/* Deschide un socket */
if ((sd = socket (AF_INET, SOCK_STREAM, 0)) < 0)
ERR ("socket", 1);
/* Obtine adresa IP a serverului */
if (!(hp = gethostbyname (argv[1])))
ERR ("gethostbyname", 2);
/* Pregateste adresa pentru conexiune */
memset ((char *) &serv_addr, 0, sizeof (serv_addr));
serv_addr.sin_family = AF_INET;
memcpy (hp->h_addr, (char *) &serv_addr.sin_addr.s_addr,
hp->h_length);
serv_addr.sin_port = htons (PORT_SERVER);
/* Solicita conexiunea la server */
if (connect (sd, (struct sockaddr *) &serv_addr,
sizeof (serv_addr)) < 0)
ERR ("connect", 3);
/* Emite o cerere catre server */
if (send (sd, argv[2], strlen (argv[2]), 0) != 0)
ERR ("send", 4);
/* Asteapta raspunsul de la server */
if (recv (sd, dir, DIRSIZE, 0) < 0)
ERR ("recv", 5);
/* Tipareste rezultatul */
printf ("%s\n", dir);
close (sd);
/* Pentru Windows
closesocket (sd);
*/
}

Programul 6.3 Sursa clientului rdct.c


In programul client, datele de intrare se preiau din linia de comand: argv[1] conine adresa Internet a
serverului i argv[2] conine numele directorului. A doua adugire esenial este obinerea adresei IP din
adresa Internet a serverului (folosind apelul gethostbyname) i depunerea acesteia n adresa socket.
De remarcat faptul c n programul 1.3 sunt cteva linii de comentariu care prezint adugirile necesare
pentru rularea clientului sub Windows.
Programul 1.4 este sursa serverului (rdst.c). Acest server ateapt ntr-o bucl conexiunile clienilor, iar
pentru fiecare nou client conectat, creeaz un proces fiu pentru tratarea interaciunii respective.
#include "read_dir.c"
#include <rd.h>
main ()
{
char dir[DIRSIZE];
int sd, fd, len_addr;

SO2 - Comunicatii si SO distribuite

53

struct sockaddr_in serv_addr, clie_addr;


signal (SIGCHLD, SIG_IGN); /* Pentru evitare zombie */
/* Creeaza un socket */
if ((sd = socket (AF_INET, SOCK_STREAM, 0)) < 0)
ERR ("socket", 1);
/* Pregateste adresa server */
memset ((char *) &serv_addr, 0, sizeof (serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl (INADDR_ANY);
serv_addr.sin_port = htons (PORT_SERVER);
/* Leaga sd de adresa server */
if (bind (sd, (struct sockaddr *) &serv_addr,
sizeof (serv_addr)) != 0)
ERR ("bind", 2);
/* Listen */
if (listen (sd, 5) != 0)
ERR ("listen", 3);
/* Bucla principala server */
for (;;) {
/* Accepta o conexiune de la un client */
if ((fd = accept (sd, (struct sockaddr *) &clie_addr,
&len_addr)) < 0)
ERR ("accept", 4);
/* Primeste cererea de la client */
if (recv (fd, dir, DIRSIZE, 0) < 0)
ERR ("recv", 5);
/* Deserveste clientul in proces separat */
if (fork () == 0) {
close (sd);
read_dir (dir);
/* Trimite raspunsul la cerere */
if (send (fd, dir, strlen (dir), 0) < 0)
ERR ("send", 6);
close (fd);
exit (0);
}
}
}

Programul 6.4 Sursa serverului rdst.c


In continuare, se compileaz sursa programului server i lanseaz n execuie, n background:
$
$

cc -o
rds &

rds

rdst.c

6.6.2 Client FTP noninteractiv


Dup cum se tie de la cursul de reele de calculatoare, FTP este un protocol de comunicaii situal la cel mai
nalt nivel n modelul OSI. Prin urmare, FTP este un protocol la nivel de aplicaie. Acest protocol este
conceput pentru a fi folosit:

SO2 - Comunicatii si SO distribuite

54

prin intermediul liniei de comand;


prin intermediul interfeelor grafice;
din cadrul aplicaiilor proprii.

Protocolul FTP utilizeaz o terminologie proprie, definit prin specificaiile RFC959, aflate la adresa
http://www.faqs.org/rfcs/rfc959.html:

access controls defineste drepturile de acces ale utilizatorului la sistem


control connection calea de comunicaie ntre cele dou interpretoare de protocoale: USER-PI
i SERVER-PI, pentru schimbul de comenzi.
data connection conexiune ful duplex prin care de transfer datele
DTP Data Transfer Process
End-of-Line separatorul de sfrit de linie
EOF condiia de sfrit de fiier
PI interpretorul de protocol implementat att de partea serverului ct i de partea clientului

Modelul conexiunii FTP este ilustrat n fig. 1.4.


Figura 6.4 Conexiunile necesare pentru FTP
Interfata
utilizator

Server PI

Comenzi
FTP
Raspunsuri
FTP

Sistemul
de fisiere

Server
DTP

Conexiunea

Utilizator

Utilizator
PI

Utilizator
DTP

Sistemul
de fisiere

datelor

Dup cum se vede protocolul FTP are nevoie de dou conexiuni pentru a putea transfera date, una pentru
schimbul de comenzi ntre PI-urile client i server i una pentru transferul de date.
Aplicatia Client FTP.cpp
Aplicaia urmtoare este un client FTP noninteractiv folosit pentru trimiterea fiierelor de pe maina local
pe un server la distant. Noninteractivitatea este dat de posibilitatea de a configura parametri de lucru
(adrese, parole, directoare i fiiere) cu ajutorul unui fiier de configurare.
In momentul de fa acest client de FTP este o parte din nucleul aplicaiilor de cutare de persoane n
reeaua UBBNET, este utilizat n aplicaia de consultare a notelor pentru cursanii nvmntului la
distan, respectiv face parte din nucleul aplicaiilor de backup al serverelor de comunicaii din reeaua
UBBNET.
Sursa ClientFTP.cpp
#include <condefs.h>
#pragma hdrstop
#pragma argsused
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <stdlib.h>
#include <winsock.h>
#include <fcntl.h>

SO2 - Comunicatii si SO distribuite

55

#include <io.h>
int configReadFtp(char *configfile, int port,
char *ip, char *lip,
char *user, char *pass,
char *dir, char *ldir,
char *files, int *nrfiles) {
// Functia de citire a configuratiei clientului ftp.
// Citirea se face din fisierul specificat de configfile
// Intoarce 0 la configurare reusita sau -1 la esec
int i;
FILE *fConf;
char temp[255], *p, *q, *r;
if ((fConf=fopen(configfile, "r"))==NULL)
return (-1); // Codul -1 = eroare la citirea fisierului de configurare
for ( (*nrfiles)=0, r=files; ; ) {
p = fgets(temp, 255, fConf); // Citeste o linie din fisierul de configurare
if (p == NULL)
break; // terminat citirea fisierului
for( q=p+strlen(p)-1; ((*q)<=' ')&&(q-p>0); q--);
*(q+1) = '\0'; // Ignora sfarsit de linie
if (strlen(p) <=2)
continue; // Ignorarea liniilor scurte
if (p[0] == '#')
continue; // Ignorarea liniilor comentariu
if ((q = strstr(p, "=")) == NULL) {
strcpy(r, temp); // Copiaza nume fisier de transferat
r += strlen(r) + 1; // la fisierul urmator
(*nrfiles)++;
continue;
} //Linie nume de fisier
q++;
for (i=0; i<q-p; i++)
p[i] = tolower(p[i]); // transformat nume in litere mici
if (strstr(p, "localip=") != NULL) {
for (i=0; i<strlen(q); i++)
if (q[i] == '.')
q[i] = ','; //IP local +port
strcpy(lip, q);
// au octetii separati
strcat(lip, ","); // prin virgula
itoa(port/256, temp, 10);
strcat(lip, temp);
strcat(lip, ",");
itoa(port%256, temp, 10);
strcat(lip, temp);
continue;
} //IPlocal
if (strstr(p, "serverip=") != NULL) {
strcpy(ip, q); // Copiaza IP server
continue;
} //IPserver
if (strstr(p, "user=") != NULL) {
strcpy(user, q); // Copiaza user
continue;
} //user
if (strstr(p, "password=") != NULL) {
strcpy(pass, q); // Copiaza parola
continue;
} //password
if (strstr(p, "remotedir=") != NULL) {
strcpy(dir, q); // Copiaza director la distanta
continue;
} //remotedir
if (strstr(p, "localdir=") != NULL) {
strcpy(ldir, q); // Copiaza director local

SO2 - Comunicatii si SO distribuite

56

continue;
} //localdir
}//for
fclose(fConf);
return(0); // terminarea normala a fixarii configuratiei
}//configReadFtp
int authFtp(struct sockaddr_in *saddr, char *ip, char *user, char *pass) {
// Functia de autenticicare a unui client FTP.
// Deschide conexiunea de control si autentifica ip, user si parola.
// Intoarce >0 (descriptorul socket) la succes sau <0 la esec/
int sock;
char mesaj[1024];
// creare socket
sock = socket(AF_INET,SOCK_STREAM,0);
if (sock < 0)
return (-1); // Eroare la creare socket
memset((char *)saddr, 0, sizeof(struct sockaddr));
saddr->sin_family=AF_INET;
saddr->sin_addr.s_addr=inet_addr(ip);
saddr->sin_port=htons(21);
// conectarea la server
if(connect (sock, (struct sockaddr*)saddr, sizeof(struct sockaddr_in)) < 0)
return (-2); // Eroare la connect
//preluare mesaj initial server
if (recv(sock, mesaj, 1024, 0) <= 3)
return (-3); // eroare rcv mesaj initial
if (strstr(mesaj, "220") != mesaj)
return(-4); // Trebuie sa raspunda 220 - awaiting input
//Trimitere nume de user la server si asteptare raspuns
strcpy(mesaj,"user ");
strcat(mesaj, user);
strcat (mesaj,"\n");
if (send(sock, mesaj, strlen(mesaj), 0) != strlen(mesaj))
return (-5); // transmitere eronata user
if (recv(sock, mesaj, 1024, 0) <= 3)
return (-6); // eroare raspuns user
if (strstr(mesaj, "331") != mesaj)
return(-7); // Trebuie sa raspunda 331 - User OK
//Trimitere parola la server si asteptare raspuns
strcpy(mesaj,"pass ");
strcat(mesaj, pass);
strcat (mesaj,"\n");
if (send(sock, mesaj, strlen(mesaj), 0) != strlen(mesaj))
return (-8); // transmitere eronata parola
if (recv(sock, mesaj, 1024, 0) <= 3)
return (-9); // eroare raspuns parola
if (strstr(mesaj, "230") != mesaj)
return(-10); // Trebuie sa raspunda 230 - User login
// Intoarce socketul de control
return (sock);
} //authFtp
int setContextFtp(int sock, char *type, char *dir) {
//Functia de fixare a contextului FTP: tipul transferului:
// ascii sau binar (type)
// directorul curent de pe serverul ftp (dir)
// Intoarce 0 la context fixat sau <0 la esec.
char mesaj[1024];

SO2 - Comunicatii si SO distribuite

57

//Trimite comanda TYPE si asteapta confirmarea


strcpy(mesaj,"TYPE ");
strcat(mesaj, type);
strcat(mesaj, "\n");
if (send(sock, mesaj, strlen(mesaj), 0) != strlen(mesaj))
return (-11); // transmitere eronata type
if (recv(sock, mesaj, 1024, 0) <= 3)
return (-12); // eroare raspuns type
if (strstr(mesaj, "200") != mesaj)
return(-13); // Trebuie sa raspunda 200 - Command Ok
//Trimite comanda CWD si asteapta confirmarea
strcpy(mesaj,"CWD ");
strcat(mesaj, dir);
strcat(mesaj,"\n");
if (send(sock, mesaj, strlen(mesaj), 0) != strlen(mesaj))
return (-14); // transmitere eronata director curent
if (recv(sock, mesaj, 1024, 0) <= 3)
return (-15); // eroare raspuns cwd
if (strstr(mesaj, "250") != mesaj)
return(-16); // Trebuie sa raspunda 250 - Requested file action Ok
return (0); // context fixat
}//setContextFTP
int putAsciiFtp(int sockc, char *ldir, int port, char *files, int nrfiles) {
//Deschidere conexiunea de date. Socketul asculta pe masina locala pe
// portul port. La el se va conecta serverul de FTP pentru a realiza
// transferul efectiv al fisierelor.
// Intoarce 0 la derulare normala,
// <0 la erori de conexiune sau
// >0 (al catelea fisier este in transfer) la erori de transfer fisiere .
//
//
//
//
//

Aceasta functie este conceputa pentru a face put de fisiere text (ASCII),
deci fisierele locale sunt tratate cu: fopen, fgets, fputs, fclose.
Pentru a face operatii get in loc de put, se va transmite RETR in loc de STOR.
Pentru schimburi (get, put) in mod binar, se vor folosi functiile:
open, read, write, close.
char mesaj[1024], *r;
struct sockaddr_in sockd; // Socket de asteptare a transferului de date
struct sockaddr_in socke; // Socket pe care ftp trimite date
int socketd, sockete, fd, lung, i;
FILE *ft;
socketd = socket(AF_INET, SOCK_STREAM, 0);
if (socketd < 0)
return(-20); // eroare la deschidere socket de date
memset((char *)&sockd, 0, sizeof(sockd));
sockd.sin_family = AF_INET;
sockd.sin_addr.s_addr = htonl(INADDR_ANY);
sockd.sin_port = htons(port);

// rezervarea portului in kernel


if( bind(socketd,(struct sockaddr *) &sockd, sizeof(sockd)) <0)
return (-21); //Eroare la bind
if (listen(socketd, 2) < 0)
return (-22); // Eroare la listen
//Se trimit continuturile fisierelor
for (i=0, r=files; i<nrfiles; i++, r+=strlen(r)+1) {
// Pentru fiecare fisier specificat in fisierul de configurare
// se creeaza o conexiune inversa pentru transmiterea fisierelor

SO2 - Comunicatii si SO distribuite

58

// Trimite comanda PORT si asteapta raspunsul


strcpy(mesaj,"port ");
strcat(mesaj, ldir);
strcat(mesaj,"\n");
if (send(sockc, mesaj, strlen(mesaj), 0) != strlen(mesaj))
return (-23); // transmitere eronata port
if (recv(sockc, mesaj, 1024, 0) <= 3)
return (-24); // eroare raspuns port
if (strstr(mesaj, "200") != mesaj)
return(-25); // Trebuie sa raspunda 200 - Command Ok
// Trimite comanda STOR si asteapta raspunsul
strcpy(mesaj,"stor ");
strcat(mesaj, r);
strcat(mesaj,"\n");
if (send(sockc, mesaj, strlen(mesaj), 0) != strlen(mesaj))
return (-26); // transmitere eronata stor
if (recv(sockc, mesaj, 1024, 0) <= 3)
return (-27); // eroare raspuns stor
if (strstr(mesaj, "150") != mesaj)
return(-28); // Trebuie sa raspunda 150 - Open ascii connection
// Exista conexiune, trimite un fisier
lung = sizeof(socke);
fd=accept(socketd,(struct sockaddr *) &socke, &lung);
if (fd < 0)
return (-30); // eroare la accept
if ((ft = fopen(r, "r")) == NULL)
return (-31); // eroare la deschiderea fisierului
// Bucla de trimitere a continutului fisierului
for ( ;fgets(mesaj, 1024, ft) != NULL; )
if (send(fd, mesaj, strlen(mesaj), 0) != strlen(mesaj))
return (i+1); // eroare la transmiterea celui de-al i-lea fisier
fclose(ft);
close(fd);
shutdown(fd,2);
// Raspunsul de la transmiterea unui fisier
if (recv(sockc, mesaj, 1024, 0) <= 3)
return (-33); // eroare raspuns transmitere fisier
}//end for
close(socketd);
return (0); // terminare normala
}//putFTP
int main(int argc, char* argv[]) {
// Plecand de la fisierul de configurare CONFIG_FILE se transfera o
// serie de fisiere ASCII de la client la un server de FTP
// Macrou pentru erori
#define ERR(S,N) {fprintf(stderr,"\n%d ",N);perror(S);exit(abs(N));}
// Constante
#define PORT 1234
#define CONFIG_FILE ".\\config.ftp"
int socketc, nrFile;
struct sockaddr_in sockc; // Socket de conexiune (la port 21)
char IP[1024], LIP[1024], USER[1024], PASS[1024],
DIR[1024], LDIR[1024], argFile[50*255];
WORD wVersiune;
WSADATA wDate;
int wEroare, i;

SO2 - Comunicatii si SO distribuite

59

char *r;
if ((i = configReadFtp(CONFIG_FILE, PORT, IP, LIP, USER, PASS, DIR, LDIR,
argFile, &nrFile)) < 0)
ERR("Eroare la citirea fisierului de configurare", i);
wVersiune = MAKEWORD((1),(1));
wEroare = WSAStartup(wVersiune, &wDate);
if (wEroare!=0)
ERR("Winsock not supported..\n", wEroare);
if ((socketc = authFtp(&sockc, IP, USER, PASS)) < 0)
ERR("Eroare de autentificare FTP", socketc);
if ((i = setContextFtp(socketc, "A", DIR)) < 0)
ERR("Eroare la stabilire context FTP", i);
if ((i = putAsciiFtp(socketc, LIP, PORT, argFile, nrFile)) != 0)
ERR("Eroare la transferurile de fisiere", i);
close(socketc);
printf("S-au transferat pe server fisierele:\n");
for (i=0, r=argFile; i<nrFile; i++, r+=strlen(r)+1 )
printf("%s\n", r);
printf("Pentru continuare tastati <ENTER>. Pentru intrerupere <CTRL/C>");
gets(IP);
return 0;
}//main()

Programul CGI GetNote.c este:


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
main(int c, char *a[]) {
// CGI: Primeste la intrare un numar de serie, un numar de semestru
// si un cod de acces al unui student: prima litera din nume,
// prima din prenume si numarul matricol.
// Intoarce pagina html care cuprinde notele, sau un mesaj de eroare
char antet[1024], student[1024], *p, *q,
fisier[50], ser[50], sem[50], cod[50], wcod[50];
int i;
FILE *fe;
strcpy(antet, getenv("QUERY_STRING"));
strcat(antet, "&");
p = strstr(antet, "ser=");
for (p+=4, i=0; *p != '&'; p++, i++)
ser[i] = *p;
ser[i] = '\0';
p = strstr(antet, "sem=");
for (p+=4, i=0; *p != '&'; p++, i++)
sem[i] = *p;
sem[i] = '\0';
p = strstr(antet, "cod=");
for (p+=4, i=0; *p != '&'; p++, i++)
cod[i] = *p;
cod[i] = '\0';
for (i=0; i<strlen(cod); i++)
cod[i] = tolower(cod[i]);
strcpy(fisier, ser);
strcat(fisier, ".");
strcat(fisier, sem);
fe = NULL;

SO2 - Comunicatii si SO distribuite

60

if ((strlen(ser)<1) || (strlen(sem)<1) || (strlen(cod)<3))


goto ERR; // serie, semestru sau cod eronate
fe = fopen(fisier, "r");
if (fe == NULL)
goto ERR; // serie/semestru eronate
fgets(antet, sizeof(antet), fe);
antet[strlen(antet)-1] = '\0'; // sters \n
for ( ; ; ) { // cautarea studentului
p = fgets(student, sizeof(student), fe);
if (p == NULL)
goto ERR; // nu s-a gasit studentul
student[strlen(student)-1] = '\0'; // sters \n
wcod[0] = student[0];
p = strchr(student, '\t') + 1;
wcod[1] = p[0];
p = strchr(p, '\t') + 1;
for (i=0; p[i] != '\t'; i++)
wcod[i+2] = p[i];
wcod[i+2] = '\0';
for (i=0; i< strlen(wcod); i++)
wcod[i] = tolower(wcod[i]);
if (strcmp(cod, wcod) == 0)
break; // l-a gasit
} // sfarsit ciclul de cautare a studentului
fclose(fe);
// Scrierea textului de raspuns pozitiv
printf("Content-type: text/html\n\n");
printf("<html><head><title>");
printf("Note de la seria %s semestrul %s", ser, sem);
printf("</title></head><body><h3>");
printf("Note de la seria %s semestrul %s", ser, sem);
printf("</h3><table>");
for ( p=antet, q=student; ; ) {
for ( i=0; p[i] != '\t'; i++)
ser[i] = p[i];
ser[i] = '\0';
p += i+1;
for ( i=0; q[i] != '\t'; i++)
sem[i] = q[i];
sem[i] = '\0';
q += i+1;
printf("<tr><td align=\"right\">%s:&nbsp;</td><td><b>%s</b></td></tr>",
ser, sem);
if (strchr(p, '\t') == NULL)
break;
} // terminat scriere tabel
printf("</table>");
goto STOP; // spre terminarea CGI
ERR:
// Scrierea textului de raspuns negativ
if (fe != NULL)
fclose(fe);
printf("Content-type: text/html\n\n");
printf("<html><head><title>");
printf("Note de la seria %s semestrul %s", ser, sem);
printf("</title></head><body><h3>Date eronate!</h3><p>");
printf("<i>Ati solicitat:</i> ");
printf("Seria: <b>%s</b> ", ser);
printf("Semestrul: <b>%s</b> ", sem);
printf("Codul: <b>%s</b>", cod);
printf("<p><h4>Aceste date nu sunt toate corecte, ");
printf("sau nu s-a transmis inca fisierul cu note!</h4>");
STOP:

SO2 - Comunicatii si SO distribuite

61

printf("</body></html>");
} // main

Textul client CerNote.html este:


<html><head><title>Solicitare note</title></head>
<body>
<form method="get" action="./cgi-bin/GetNote.cgi">
<h3>Pentru obtinerea unor note, completati formularul:</h3>
<table>
<tr><td>Numarul seriei de curs (cifre arabe):</td>
<td><input type="text" name="ser"></td></tr>
<tr><td>Numarul semestrului (cifre arabe):</td>
<td><input type="text" name="sem"></td></tr>
<tr><td>Codul de acces:</td>
<td><input type="text" name="cod"></td></tr>
<tr><td><input type="reset" value="Anuleaza completarea"></td>
<td><input type="submit" value="Solicita notele"></td></tr>
</table>
<p><em>Precizarea 1: </em>Desi se obisnuieste scrierea lor si cu
cifre romane, numarul seriei si numarul semestrului se cer
cu cifre arabe.
<p><em>Precizarea 2: </em>Codul de acces este format din doua
litere (indiferent ca sunt mari sau mici), urmate de numarul matricol.
Prima litera este prima litera a primului nume de familie, in
conformitate cu buletinul, <em>pentru doamne se va lua in considerare
numele de fata</em>. A doua litera este prima litera a primului prenume,
tot in conformitate cu buletinul.
<p><em>Exemplu: </em>Pentru a obtine notele din seria IV, sem III, Doamna
avand numele de familie
<i><b>I</b>onescu - Galati (cas Vasilescu)</i>,
iar prenumele <i><b>E</b>lena Adina</i>, cu numarul
matricol <b><i>731</i></b>, va trebui sa completeze:
<center><table><tr>
<td> Seria: </td><td><b> 4 </b></td><td> Semestrul: </td><td><b> 3 </b></td>
<td> Codul: </td><td><td><b> ie731 </b></td>
</tr></table></center>
</form></body></html>

Programul de filtrare Filtru.cpp este:


#include <condefs.h>
#pragma hdrstop
#pragma argsused
#include <stdio.h>
#include <dir.h>
#include <string.h>
#include <ctype.h>
int main(int argc, char *argv[]) {
struct ffblk sfisier;
char fisier[50], fisiere[50][50], fisieretxt[50][50],
antet[1024], student[1024], ser[1024], sem[1024], tab[1024],
*p, *q, *r;
int fd, n, i, j, k, t, nf=0;
FILE *fe, *fr;
fd = findfirst("*.txt", &sfisier, 0);
for ( ; !fd; fd = findnext(&sfisier) ) { // ciclul fisier dupa fisier
strcpy(fisier, sfisier.ff_name);
printf("\nSe va filtra \"%s\"\n", fisier);
strlwr(fisier); // fa totul in litere mici
p = strstr(fisier, "ser"); // p la inceputul lui ser
if (p == NULL)

SO2 - Comunicatii si SO distribuite

62

continue; // lipseste seria


for ( p += 3 ; (!isdigit(*p) && strlen(p)); p++); // la cifra
if (*p == 0)
continue; // lipseste numarul seriei
for ( i=0; isdigit(*p); ser[i]=*p, i++, p++); // cifre serie
ser[i] = '\0'; // zeroul terminal
p = strstr(p, "sem");
if (*p == 0)
continue; // lipseste semestrul
for ( p += 3 ; (!isdigit(*p) && strlen(p)); p++); // la cifra
if (*p == 0)
continue; // lipseste numarul seriei
for ( i=0; isdigit(*p); sem[i]=*p, i++, p++); // cifrele semestru
sem[i] = '\0'; // zeroul terminal
strcat(ser, ".");
strcat(ser, sem);
printf("\tFsierul \"%s\" (serie.semestru) va contine informatiile
filtrate\n", ser);
// Incepe filtrarea fisierului
fe = fopen(fisier, "r");
for ( ; ; ) { // ignorarea pana la antet
p = fgets(antet, sizeof(antet), fe);
if (p == NULL)
goto NEXTFILE; // fisier eronat
p = strstr(antet, "Nume\t");
if (p == antet)
break;
} // preluat prima linie a antetului
antet[strlen(antet)-1] = '\0';
strcat(antet, "\t");
for ( i=0, n=0; i < strlen(antet); i++)
if (antet[i] == '\t') {
tab[n] = '\t'; // taburi suplimentare
n++;
}
tab[n] = '\0';
if ((n < 4) || (strlen(antet) < 2*n))
goto NEXTFILE; // campuri scurte in antet
printf("\tAntetul are %d campuri, adica:\n", n);
for ( ; ; ) { // preluat completarile la antet
p = fgets(student, sizeof(student), fe);
if (p == NULL)
goto NEXTFILE; // fisier eronat
student[strlen(student)-1] = '\0';
strcat(student, tab); // completat cu taburi
for (p=student, i=0; i<n; p=strstr(p,"\t")+1, i++);
*p = '\0'; // retinut numarul exact de taburi
if (student[0] != '\t')
break; // terminat completarile
p = student + 1; // de aici ia completarea
q = strstr(p, "\t"); // pana aici tine completarea
r = strstr(antet+1, "\t");
r = strstr(r+1, "\t"); // de aici se pune
for (i=1; i<n; i++, r=strstr(q-p+r+1,"\t"), p=q+1, q=strstr(p,"\t")) {
if (p == q)
continue;
for ( j=strlen(r), k=j+q-p; j >= 0; j--, k--)
r[k] = r[j]; // fa loc completarii
for ( j=0; j<q-p; j++)
r[j] = p[j]; // muta completarea
} // terminat adaugirea curenta
} // terminat adaugirile la antet

SO2 - Comunicatii si SO distribuite

63

fr = fopen(ser, "w");
strcat(antet, "\n");
fputs(antet, fr); // scrie antetul
strcat(student,"\n");
t = 0; // numarul de studenti filtrati
if (strlen(student) >= n + 6) {
fputs(student, fr);
t++;
} // ignora liniile prea scurte
for (i=0; i<n-1; i++)
*strchr(antet, '\t') = '|'; // pentru afisare
antet[strlen(antet)-2] = '\0';
printf("\t\"%s\"\n", antet);
for ( ; ; ) { // preluat liniile de dupa antet
p = fgets(student, sizeof(student), fe);
if (p == NULL)
break; // terminat copierea
student[strlen(student)-1] = '\0';
strcat(student, tab); // completat cu taburi
for (p=student, i=0; i<n; p=strstr(p,"\t")+1, i++);
*p = '\0'; // retinut numarul exact de taburi
strcat(student, "\n");
if (strlen(student) >= n + 6) {
fputs(student, fr);
t++;
} // ignora liniile prea scurte
} // depus liniile in fisierul filtrat
fclose(fr); // inchis fisierul filtrat
printf("\t\"%s\" contine %d studenti\n", ser, t);
strcpy(fisiere[nf], ser);
strcat(fisiere[nf], "\n"); //numele fisierului filtrat
strcpy(fisieretxt[nf], fisier);
strcat(fisieretxt[nf], "\n"); // numele fisierului din care s-a filtrat
nf++;
printf("S-a trimis \"%s\" spre depunere server\n\n", ser);
NEXTFILE:
fclose(fe);
} // Terminat filtrarea fisierelor *.txt
// Urmeaza pregatirea fisierului de configurare si a celui de stergeri
if ((fe = fopen("Gconfig.ftp", "r")) == NULL)
return (1);
fr = fopen("config.ftp", "w");
for ( ; ; ) {
p = fgets(antet, sizeof(antet), fe);
if (p == NULL)
break;
if (strlen(p) <= 2)
continue; // ignora liniile scurte
if (p[0] == '#')
continue; // ignora liniile comentariu
if ((q=strstr(p, "=")) == NULL)
continue; // ignora liniile ce nu contin parametri
q++;
for (i=0; i < q-p; i++)
p[i] = tolower(p[i]); // numele de camp cu litere mici
if (strstr(p, "password=") != NULL)
for(i=0; i<strlen(q); i++) // DeCripteaza parola citita
q[i]=(isdigit(q[i]))?('z'+'0'-q[i])
:((isupper(q[i]))&&(q[i]<='P'))?('p'+'A'-q[i])
:((isupper(q[i]))&&(q[i]>='Q'))?('Z'+'Q'-q[i])
:((islower(q[i]))&&(q[i]<='p'))?('P'+'a'-q[i])
:((islower(q[i]))&&(q[i]>='q'))?('9'+'q'-q[i])
:(q[i])
;

SO2 - Comunicatii si SO distribuite

64

fputs(antet, fr);
}//for
fclose(fe);
fe = fopen("stergeri.bat", "w"); // creaza scriptul de stergeri
for (i=0; i<nf; i++) {
fputs(fisiere[i], fr); // scrie numele fisierelor de transmis
fprintf(fe, "del %s", fisiere[i]);
fprintf(fe, "del %s", fisieretxt[i]);
}//for
fclose(fr);
fclose(fe);
printf("Au fost filtrate %d fisiere.\n", nf);
printf("Pentru continuare tastati <ENTER>. Pentru intrerupere <CTRL/C>");
gets(antet); // asteapta un enter
return (0); // Terminare normala
} // main