Servicii de comunicatie prin mesaje în retele Novell
Serviciile de comunicație prin mesaje permit programelor de aplicație:
a) să emită mesaje de pâna la 55 de octeți în vederea difuzarii lor la mai multe destinații
b) să stabileasca unul sau mai multe canale de mesaje cu o anumită stație de lucru legată la același file server. Un astfel de canal oferă posibilitatea transmiterii de mesaje de pâna la 126 de octeți.
Difuzarea de mesaje și comunicația prin canale consumă timp calculator la server. Pentru a avea o adevarată comunicație de la egal la egal între stațiile de lucru, programele de aplicații pot să folosească funcțiile IPX sau SPX sau NetBIOS. Aceste funcții nu folosesc timp UC server și deci oferă performanțe mai bune și o flexibilitate crescută. Pentru serviciul de difuzare a mesajelor, fiecare conexiune a unui file server are asociată un buffer de 55 de octeți pentru serviciul de comunicație prin canale, serverul menținând pentru fiecare cone 13513w2215n xiune o coadă de mesaje (capacitatea maxima a cozii este de 6 mesaje). În mod normal, odată cu conexiunea se trimite un mesaj spre difuzare către o altă conexiune, acesta este depus în bufferul de mesaje difuzate sau în coada de mesaje primite ale conexiunii destinatare de unde este preluat de supervizor (shell) și afișat pe linia cea mai de jos, a 25-a linie a ecranului.
Fiecare conexiune are un mod de tratare a mesajelor (un nr numai între 0 și 3, care poate fi modificat prin program), care precizează dacă bufferul destinat mesajelor difuzate este deschis sau nu și dacă supervizorul are sau nu voie să preia automat mesajele difuzate.
Funcțiile de comunicare prin mesaje sunt folosite de programele utilitare SEND, CASTON și CASTOFF, care se folosesc pentru a emite mesaje în vederea difuzarii, să permită sau să interzică recepționarea mesajelor difuzate. Mesajele transmise cu ajutorul acestor funcții pot fi înregistrate într-un fișier jurnal special, accesibil administratorului rețelei.
Fișiere antet necesare:
#include <nit.h>
#include <niterror.h>
BroadcastToConsole
Trimite un mesaj care va fi afișat la consola serverului implicit. Mesajele afișate la consolă șterg mesajele precedente.
Parametri:
char *message șir de caractere conținând mesajul de trimis. Lungimea maximă este de 60 de caractere inclusiv NULul terminător. Sunt permise numai caracterele imprimabile din setul ASCII.
Rezultat:
int SUCCESSFULL
MESSAGE_QUEUE_FULL
IO_FAILURE (lipsă spațiu dinamic de lucru).
CheckPipeStatus
Determină starea uneia sau a mai multor canale de mesaje.
Parametri:
WORD *connectionList tablou conținând numerele de conexiune ale stațiilor la care este legat fiecare dintre canalele asupra cărora să face interogarea.
BYTE *resultList fiecare element din acest tablou va primi ca valoare un cod indicând starea canalului identificat de elementul corespunzator din connectionList. Sunt definite urmatoarele valori :
0x00 -- canal în stare de funcționare
0xFE -- cealaltă conexiune nu a deschis canalul corespunzător
0xFF -- canalul nu a fost deschis sau numărul conexiunii este eronat.
WORD connectionCount numărul de canale (elemente în tablourile precedente).
Rezultat:
int SUCCESSFUL
CloseMessagePipe
Închide unul sau mai multe canale de mesaje.
Parametri:
WORD *connectionList tablou conținând numerele de conexiune ale stațiilor la care este legat fiecare dintre canalele care trebuie închise
BYTE *resultList fiecare element din acest tablou va primi ca valoare un cod indicând starea canalului identificat de elementul corespunzător din connectionList. Sunt definite următoarele valori :
0x00 -- canalul a fost închis cu succes
0xFD -- eroare, cealaltă conexiune nu mai este validă
0xFF -- eroare, canalul nu era deschis.
WORD connectionCount numărul de canale (elemente în tablourile precedente).
Rezultat:
int SUCCESSFULL
MESSAGE_QUEUE_FULL
IO_FAILURE (lipsă spațiu dinamic de lucru).
GetBroadcastMessage
Preia un mesaj transmis prin difuzare. Apelarea acestei funcții are sens numai
dacă modul de tratare a mesajelor difuzate este 2 sau 3.
Parametri:
char *messageBuffer va recepționa mesajul (cel mult 55 de caractere, inclusiv NUL-ul terminator). Dacă nici un mesaj nu este disponibil, atunci messageBuffer[0] va lua valoarea '\0' (lungimea minimă a unui mesaj este 1).
Rezultat:
int SUCCESSFULL
MESSAGE_QUEUE_FULL
IO_FAILURE (lipsă spațiu dinamic de lucru).
GetBroadcastMode
Permite aflarea modului curent de tratare a mesajelor difuzate. Un mesaj din
partea serverului poate elimina din buffer un mesaj din partea unei stații de lucru.
Rezultat:
BYTE 0 -- mesajele sunt admise atât din partea altor stații de lucru cât și din partea serverului. Supervizorul stației preia automat și afișează fiecare mesaj.
1 -- mesajele sunt admise numai din partea serverului. Supervizorul stației preia automat și afisează fiecare mesaj.
2 -- mesajele sunt admise numai din partea serverului. Este sarcina utilizatorului să preia mesajele.
3 -- sunt admise mesaje atât din partea serverului cât și a altei stații de lucru. Este sarcina utilizatorului să preia mesajele.
GetPersonalMessage
Preia un mesaj din coada de mesaje asociată stației de lucru.
Parametri:
char *messageBuffer primește ca valoare un șir de caractere reprezentând cel mai vechi mesaj din coadă (cel mult 127 de caractere, inclusiv NUL-ul).
WORD *connectionNumber primește ca valoare numărul conexiunii care a emis mesajul, sau 0 dacă nu există nici un mesaj în coadă.
Rezultat:
int SUCCESSFUL
IO_FAILURE (lipsă spațiu dinamic de lucru).
LogNetworkMessage
Depune un mesaj în fișierul NET$LOG.MSG al serverului implicit. Intrarea în fișier va avea următorul format:
luna/zi/an ore:minute STN număr_stație: mesaj
Funcția poate fi utilizată de utilitare sau de programe de aplicație care au nevoie să înregistreze informații, de exemplu cu scopul de a le folosi pentru contabilitate.
Parametri:
char *message șir de caractere imprimabile conținând mesajul de înregistrat (cel mult 80 de caractere, inclusiv NUL-ul).
Rezultat:
int SUCCESSFUL.
OpenMessagePipe
Crează o jumatate de canal de comunicație între stația de lucru și una sau mai multe conexiuni, cealaltă jumatate a canalului (canalelor) trebuie creată de conexiunea (conexiunile) destinatară cu ajutorul aceleiași funcții.
Parametri:
WORD *connectionList un tablou conținând numerele conexiunilor la care trebuie conectată stația de lucru. Pentru fiecare element din acest tablou se află un element corespunzator în tabloul resultList.
BYTE *resultList elementele acestui tablou primesc ca valoare un cod care indică rezultatul încercării de a deschide o conexiune între stații de lucru și conexiunea indicată de elementul corespunzator din connectionList. Valorile acestui cod pot fi :
0x00 -- succes, conexiunea destinatară crease deja jumatatea ei de canal,
0xFE -- canal incomplet, conexiunea destinatară există, dar nu a creat încă jumatatea ei de canal,
0xFF -- eșec, conexiunea destinatară nu există.
WORD connectionCount numărul de intrări în connectionList.
Rezultat:
int SUCCESSFUL
IO_FAILURE (lipsă spațiu dinamic de lucru).
SendBroadcastMessage
Trimite un mesaj spre difuzare la un număr de conexiuni de pe același server.
Parametri:
char *message mesaj de difuzat (cel mult 56 de caractere, inclusiv NUL).
WORD *connectionList tablou conținând numerele conexiunilor către care trebuie difuzat mesajul.
BYTE *resultList tablou ale cărui elemente primesc ca valoare un cod indicând modul în care s-a desfășurat difuzarea mesajului către conexiunea corespunzatoare din connectionList. Valorile acestui cod pot fi :
0x00 -- succes, mesajul a fost depus în bufferul de mesaje difuzate al conexiunii destinatare
0xFC -- eșec, bufferul de mesaje difuzate al conexiunii destinatare este deja plin
0xFD -- numărul conexiunii destinatare este eronat
0xFF -- eșec, conexiunea destinatară nu există sau modul ei de tratare a mesajelor difuzate nu permite acceptarea mesajului.
WORD connectionCount numărul de intrări în connectionList.
Rezultat:
int SUCCESSFUL
IO_FAILURE (lipsă spațiu dinamic de lucru).
SendPersonalMessage
Trimite un mesaj către una sau mai multe conexiuni cu care stația de lucru a deschis canale de mesaje.
Parametri:
char *message mesaj de trimis (cel mult 127 de caractere, inclusiv NUL).
WORD *connectionList tablou conținând numerele conexiunilor către care trebuie trimis mesajul.
BYTE *resultList tablou ale cărui elemente primesc ca valoare un cod indicând modul în care s-a desfășurat trimiterea mesajului către conexiunea corespunzătoare din connectionList. Valorile acestui cod pot fi :
0x00 -- success, mesajul a fost depus în bufferul de mesaje difuzate al conexiunii destinatare
0xFC -- eșec, coada de mesaje a conexiunii destinatare este deja plină
0xFE -- conexiunea destinatară nu a deschis acest canal
0xFF -- eșec, conexiunea destinatară nu există sau stația de lucru nu a deschis un canal de comunicație spre această conexiune.
WORD connectionCount numărul de intrări în connectionList.
Rezultat:
int SUCCESSFUL
IO_FAILURE (lipsă spațiu dinamic de lucru).
SetBroadcastMode
Stabileste modul în care sunt tratate mesajele difuzate destinate acestei stații de lucru.
Parametri:
BYTE broadcastMode o valoare între 0 și 3 specificând modul de tratare a mesajelor difuzate. Modul implicit este zero. Pentru semnificația valorilor vezi funcția GetBroadcastMode.
Servicii de sincronizare în rețele Novell
Serviciile de sincronizare oferă programelor de aplicație posibilitatea coordonării accesului la fișierele din rețea și la alte resurse.
Semafoare
Sistemul Netware pune la dispozitia utilizatorilor posibilitatea de a defini și folosi semafoare. Acestea pot fi folosite pentru a implementa cele mai diferite protocoale de sincronizare. Fiecărui semafor îi sunt asociate două contoare : un contor de procese care au 'deschis' semaforul (care au acces la semafor), și un contor care este decrementat la fiecare apel WaitOnSemaphore și incrementat la SignalSemaphore (contorul tipic pentru semafoare).
Etapele lucrului cu un semafor:
1) deschiderea semaforului (Open)
2) exploatarea semaforului (Wait și Signal)
3) închiderea semaforului (Close).
int OpenSemaphore(char *semaphoreName, int initialValue, long *semaphoreHandle,
WORD *openCount)
semaphoreName - numele semaforului (max. 128 de caractere, inclusiv NUL)
initialValue - valoarea inițială a semaforului. Acest parametru nu se ia în considerare decât dacă semaforul nu există și este creat. Sunt permise valori între 0 și 127.
*semaphoreHandle primește ca valoare un descriptor de semafor, care va fi utilizat în celelalte funcții
*openCount primește numărul de procese care au 'deschis' acest semafor.
Rezultat:
0x00 SUCCESSFUL
0xFE INVALID_SEMAPHORE_NAME_LENGTH
0xFF INVALID_SEMAPHORE_INITIAL_VALUE
int ExamineSemaphore(long semaphoreHandle, int *semaphoreValue,
WORD *openCount)
Examinează un semafor deschis. Depune în semaphoreValue, respectiv openCount,
valoarea contorului de semafor, respectiv numărul de procese care au deschis semaforul.
Rezultat: 0x00 SUCCESSFUL
0xFF INVALID_SEMAPHORE_HANDLE
int WaitOnSemaphore(long semaphoreHandle, WORD timeoutLimit)
Încearcă să decrementeze contorul asociat unui semafor. Dacă după decrementare acesta este mai mare sau egal cu zero, atunci procesul care a apelat Wait continuă. În caz contrar, procesul este depus într-o coada de așteptare asociată semaforului. Coada avansează la fiecare apel Signal pentru același semafor. Dacă procesul petrece în coadă mai mult de timeoutLimit unități de 1/18 sec, atunci el este scos din coadă și funcția întoarce un cod de eroare.
Rezultat:
0x00 SUCCESSFUL
0xFE TIMEOUT_FAILURE
0xFF INVALID_SEMAPHORE_HANDLE
int SignalSemaphore(long semaphoreHandle)
Încrementeaza contorul asociat semaforului. Dacă în coada de așteptare se afla vreun proces, primul proces din coadă este deblocat.
Rezultat:
0x00 SUCCESSFUL
0x01 SEMAPHORE_OVERFLOW (contorul a depașit 127)
0xFF INVALID_SEMAPHORE_HANDLE
int CloseSemaphore(long semaphoreHandle)
Închide un semafor. Pentru ca programul să recâștige accesul la acel semafor, trebuie să apeleze iarăși OpenSemaphore. Dacă acest proces era ultimul care folosea semaforul, atunci semaforul este distrus.
Rezultat:
0x00 SUCCESSFUL
0xFF INVALID_SEMAPHORE_HANDLE
Probleme
1. Imaginați aplicații în care să folosiți cât mai multe din apelurile relative la comunicația și sincronizarea distribuită în rețele Novell
2. Studiați programele filecomm.cpp, ipxcomm.cpp, pipecomm.cpp și imaginați programe de aplicații (readers-writers, cei 5 filozofi, producător-consumator, etc)
|