II. NetBios REXX
Автор: Kádár Zsolt
Дата: 12.12.1998
Источник: https://xenia.sote.hu
Язык: Венгерский
A Lan Server, Samba, vagy más termékek által használt NetBios kommunikációs protokoll is programozható REXX-bôl, ha rendelkezünk a megfelelô bôvítô DLL-lel. Én pl. a 8-as DEVCON CD-n, a \DEVTOOLS\RXNETB könyvtárban találtam meg a REXXNETB.DLL-t, amelyben megvannak mindazon segédfüggvények, amelyek a NetBios protokoll használatához szükségesek.
A függvények regisztrálása
Mielôtt használhatnánk a DLL-ben található függvényeket, természetesen regisztrálni kell azokat. Formailag csupán egyetlen függvényt tartalmaz a DLL, amely a megadott paraméterektôl függôen különbözô feladatokat végez el. Emiatt a regisztrálás is csupán egyetlen függvénye terjed ki:
CALL RxFuncAdd 'NETBIOS','REXXNETB','NETBIOSSRV'
Magától értetôdik, hogy a REXXNETB.DLL-nek jelen kell lennie a futtatott REXX program alkönyvtárában, vagy egy olyan könyvtárban, amely benne van a LIBPATH-ban, különben a regisztrálás sikertelen lesz. A DLL azt is megengedi, hogy a függvény nevét mi magunk válasszuk meg. A név ugyanis mindig az RxFuncAdd utasítás elsô paramétere lesz. Az alapértelmezett érték NETBIOS, és mi is ezt fogjuk használni.
A NetBios függvény és paraméterei
A NetBios függvényt minimum két paraméterrel kell meghívni. Az elsô paraméter határozza meg, hogy a függvény tulajdonképpen mit is csináljon, s a további paraméterek testesítik meg a kimeneti és bemeneti adatokat:
Rc = NETBIOS( funkció [ paraméterek ] ) Call NETBIOS funkció [ paraméterek ]
A használható funkciókat, paramétereket és visszatérési értékeket összefoglaltuk az alábbi táblázatban:
Funkció és szintakszis: | Paraméterek: | Visszatérési érték: |
NetBios név regisztrálása: NETBIOS( 'AddName', adapter, név ) | Adapter = 0, vagy 1, név = 16 bájtos NetBios karakterlánc | NN YY karakterlánc, NN = visszatérési érték, YY = a névhez tartozó NetBios szám, ha NN = 0 |
NetBios csoportnév regisztrálása: NETBIOS( 'AddGroupName', adapter, név ) | Adapter = 0, vagy 1, név = 16 bájtos NetBios karakterlánc | NN YY karakterlánc, NN = visszatérési érték, YY = a névhez tartozó NetBios szám, ha NN = 0 |
Kapcsolat felvétele: NETBIOS( 'Call', adapter, lokális_név, partner_név, küldési_késleltetés, fogadási_késleltetés ) | Adapter = 0, vagy 1, lokális_név = a kapcsolatot felvevô fél NetBios csoportneve, partner_név = a hívott fél csoportneve, küldési_késleltetés = a küldés maximális türelmi ideje (ms), fogadási_késleltetés = a fogadás maximális türelmi ideje (ms) | NN YY karakterlánc, NN = visszatérési érték, YY = a létrehozott szekcióhoz tartozó NetBios szám, ha NN = 0 |
Pufferek kapcsolt küldése (max. 128Kb): NETBIOS( 'Chain_Send', adapter, szekció, puffer1, puffer2 ) | Adapter = 0, vagy 1, szekció = Call vagy Listen által visszaadott NetBios szám, puffer1 és puffer2 = a küldendô pufferek | NetBios visszatérési érték |
Pufferek ellenôrzés nélküli kapcsolt küldése (max. 128Kb): NETBIOS( 'Chain_Send_NoAck', adapter, szekció, puffer1, puffer2 ) | Adapter = 0, vagy 1, szekció = Call vagy Listen által visszaadott NetBios szám, puffer1 és puffer2 = a küldendô pufferek | NetBios visszatérési érték |
A lefoglalt NetBios erôforrások felszabadítása: NETBIOS( 'Close', adapter ) | Adapter = 0, vagy 1 | NetBios visszatérési érték |
A beállított és az éppen nem használt NetBios erôforrások lekérdezése: NETBIOS( 'Config', adapter ) | Adapter = 0, vagy 1 | A visszaadott karakterlánc a következô információkat tartalmazza: beállított szekciók, beállított parancsok, beállított nevek, nem használt szekciók, nem használt parancsok, nem használt nevek |
Név törlése a NetBios táblából: NETBIOS( 'DeleteName', adapter, név ) | Adapter = 0, vagy 1, név = a törölni kívánt NetBios név | NetBios visszatérési érték |
Név keresése: NETBIOS( 'FindName', adapter, név, összetett_változó ) | Adapter = 0, vagy 1, név = a keresett NetBios név, összetett_változó = a keresés eredménye (összetett_változó.0 = találatok száma, összetett_változó.1 = a csoport, vagy az egyedi név, összetett_változó.2 (vagy magasabb) = a visszaadott adat bináris formátumban | NetBios visszatérési érték |
A szekció bezárása: NETBIOS( 'Hangup', adapter, szekció ) | Adapter = 0, vagy 1, szekció = Call vagy Listen által visszaadott NetBios szekciószám | NetBios visszatérési érték |
Kapcsolat felvétele: NETBIOS( 'Listen', adapter, lokális_név, partner_név, küldési_késleltetés, fogadási_késleltetés ) | Adapter = 0, vagy 1, lokális_név = a hívást fogadó fél NetBios csoportneve, partner_név = a hívó fél csoportneve (* = bárki), küldési_késleltetés = a küldés maximális türelmi ideje (ms), fogadási_késleltetés = a fogadás maximális türelmi ideje (ms) | NN YY karakterlánc, NN = visszatérési érték, YY = a létrehozott szekcióhoz tartozó NetBios szám, ha NN = 0 |
Adat fogadása: NETBIOS( 'Receive', adapter, szekció, méret, összetett_változó ) | Adapter = 0, vagy 1, szekció = Call vagy Listen által visszaadott NetBios szekciószám, méret = a maximálisan küldhetô adat, összetett_változó = az összetett_változó.0-ban kerül eltárolásra a fogadott adat | NetBios visszatérési érték |
Adat fogadása bárkitôl: NETBIOS( 'Receive_Any', adapter, szekció, méret, összetett_változó ) | Adapter = 0, vagy 1, szekció = AddName által visszaadott NetBios szekciószám, méret = a maximálisan küldhetô adat, összetett_változó = az összetett_változó.0-ban kerül eltárolásra a fogadott adat, az összetett_változó.1 tartalmazni fogja a küldô állomás nevét | NetBios visszatérési érték |
Körhívás fogadása: NETBIOS( 'Receive_BroadcastDatagram', adapter, szekció, méret, összetett_változó ) | Adapter = 0, vagy 1, szekció = AddName által visszaadott NetBios szekciószám, méret = a maximálisan küldhetô adat, összetett_változó = az összetett_változó.0-ban kerül eltárolásra a fogadott adat, az összetett_változó.1 tartalmazni fogja a küldô állomás nevét | NetBios visszatérési érték |
Datagram fogadása bárkitôl: NETBIOS( 'Receive_Datagram', adapter, szekció, méret, összetett_változó ) | Adapter = 0, vagy 1, szekció = AddName által visszaadott NetBios szekciószám, méret = a maximálisan küldhetô adat, összetett_változó = az összetett_változó.0-ban kerül eltárolásra a fogadott adat, az összetett_változó.1 tartalmazni fogja a küldô állomás nevét | NetBios visszatérési érték |
NetBios erôforrások lefoglalása: NETBIOS( 'Reset', adapter, szekciók, parancsok, nevek) | Adapter = 0, vagy 1, szekciók = a lefoglalandó szekciók száma, parancsok = a lefoglalandó parancsok száma, nevek = a lefoglalandó nevek száma | NetBios visszatérési érték (56 = a kért erôforrások nem elérhetôek) |
Adat küldése: NETBIOS( 'Send', adapter, szekció, adat ) | Adapter = 0, vagy 1, szekció = Call vagy Listen által visszaadott NetBios szám, adat = a küldendô adat | NetBios visszatérési érték |
Körüzenet küldése: NETBIOS( 'Send_BroadcastDatagram', adapter, szekció, adat ) | Adapter = 0, vagy 1, szekció = AddName által visszaadott értél, adat = a küldendô adat | NetBios visszatérési érték |
Datagram küldése: NETBIOS( 'Send_Datagram', adapter, szekció, fogadó_fél, adat ) | Adapter = 0, vagy 1, szekció = AddName által visszaadott értél, fogadó_fél = a partner NetBios neve, adat = a küldendô adat | NetBios visszatérési érték |
Adat ellenôrzés nélküli küldése: NETBIOS( 'Send_NoAck', adapter, szekció, adat ) | Adapter = 0, vagy 1, szekció = Call vagy Listen által visszaadott NetBios szám, adat = a küldendô adat | NetBios visszatérési érték |
NetBios üzenetek fogadása
Példaképpen nézzük meg az alábbi programot, amely a REXXNETB.DLL-ben található segédfüggvény felhasználásával NetBios üzenetek fogadására és megjelenítésére képes. A program a SysSleep és a NetBios segédfüggvények regisztrálásával indul, majd pedig definiálja a NetBios szabványnak megfelelô 16 bájt hosszúságú nevet (Kliensnev). Mivel azt szeretnénk, hogy a program bárkitôl elfogadjon üzenetet, ezért a partner nevének (Szervernev) csillagot adunk meg. Ezek után lefoglaljuk a mûködéshez szükséges NetBios erôforrásokat, bejelentjük nevünket és elraktározzuk a névhez kapott azonosító számot. Ezzel gyakorlatilag készen is vagyunk, mivel most már csak várni kell, hogy valaki elkezdjen beszélni hozzánk. Amennyiben ez bekövetkezik, akkor kiíratjuk a képernyôre a kapcsolatot kezdeményezô fél nevét, s egy végtelen hurokban elkezdjük az üzenetek fogadását és képernyôre írását. Minden üzenet vételét nyugtázzuk. Amennyiben a hívást kezdeményezô QUIT üzenetet küld, akkor befejezettnek tekintjük a kapcsolatot, s várunk a következô hívásra. A példaprogram öt párbeszéd után kilép (demó verzió :-), ezt azonban könnyedén megváltoztathatjuk a megfelelô DO-loop átírásával. Figyeljük meg, hogy a hurkokba 1 másodperces szüneteket iktattunk be. Erre azért van szükség, hogy ne terheljük le feleslegesen a futtató gép processzorát.
/* NETBIOS kliens üzenetek fogadására */ /* A NETBIOS és SysSleep függvények regisztrálása */ call RxFuncAdd 'SysSleep', 'RexxUtil', 'SysSleep' call RxFuncAdd 'netbios', 'rexxnetb', 'netbiossrv' /* A kliens és a szerver NETBIOS neveinek definiálása */ Kliensnev = Left('Kliens', 16, ' ') Szervernev = Left('*', 16, ' ') /* bárki lehet */ /* Lefoglaljuk a szükséges NETBIOS erôforrásokat */ say 'A Netbios erôforrások lefoglalása folyamatban...' Rc = netbios('Reset', 0, 1, 1, 1) if Rc = 0 then do /* Bejelentjük a nevünket és kiolvassuk a hozzátartozó számot */ parse value netbios('AddName', 0, Kliensnev) with rc name_num . say 'A 'space(Kliensnev)' Netbios száma: 'name_num say 'Várom az üzeneteket!' do i = 1 to 5 /* demó verzió, így csak 5 üzenetet fogadunk */ /* Várjuk, hogy valaki üzenetet küldjön */ parse value netbios('Listen', 0, Kliensnev, Szervernev, 0, 0) with rc lsn CallerName . if Rc = 0 then /* üzenet érkezik */ do say say '�zenet érkezik! Küldô: 'space(CallerName)', Netbios száma: 'lsn do forever Rc = netbios('Receive', 0, lsn, 1000, 'data.') if Rc = 0 then do say data.0 /*Kiíratjuk az üzenetet */ /* Nyugtázás */ call netbios 'Send',0,lsn, 'A 'space(Kliensnev)' válasza: �zenetét vettem!' end if data.0 = 'QUIT' then leave call syssleep 1 /* hogy más is kapjon CPU-t */ end call netbios 'Hangup', 0, lsn end call syssleep 1 /* hogy más is kapjon CPU-t */ end /* Visszaadjuk a lefoglalt Netbios erôforrásokat */ call netbios 'Close', 0 end else say 'A kért Netbios erôforrások nem elérhetôek (Rc = 'Rc').' exit
NetBios üzenetek küldése
Leckénk második példaprogramja az üzenetek küldését demonstrálja. A kezdés nagyon hasonlít az elôzô példában látottakra, ugyanis regisztráljuk a szükséges segédfüggvényeket és definiáljuk a saját és a partner nevét. Lefoglaljuk az erôforrásokat és bejelentjük nevünket. Ezek után felvesszük a kapcsolatot a partnerünkkel. Amennyiben sikerült a kapcsolatfelvétel, akkor megkezdjük az üzenetek beolvasását és továbbítását. A QUIT üzenet megadásakor befejezzük a társalgást, s a lefoglalt NetBios erôforrások felszabadítása után kilépünk a programból.
/* NETBIOS szerver üzenetek küldéséhez */ /* A NETBIOS függvények regisztrálása */ call RxFuncAdd 'netbios', 'rexxnetb', 'netbiossrv' /* A szerver és a kliens NETBIOS neveinek definiálása */ Szervernev = Left('Server', 16, ' ') Kliensnev = Left('Kliens', 16, ' ') /* Lefoglaljuk a szükséges NETBIOS erôforrásokat */ say 'A Netbios erôforrások lefoglalása folyamatban...' Rc = netbios('Reset', 0, 1, 1, 1) if Rc = 0 then /* sikerült */ do /* Bejelentjük a nevünket és kiolvassuk a hozzátartozó számot */ parse value netbios('AddName', 0, Szervernev) with rc name_num . say 'A 'space(Szervernev)' Netbios száma: 'name_num /* Hívjuk a klienst és kiolvassuk a számát */ parse value netbios('Call', 0, Szervernev, Kliensnev, 0, 0) with rc lsn . say 'A 'space(Kliensnev)' Netbios száma: 'lsn if Rc = 0 then /* megtaláltuk */ do do forever say say 'Adja meg a küldendô üzenetet! (QUIT = kilépés)' pull string if string = '' then iterate say 'Küldöm a következô üzenetet:' string', Címzett: 'space(Kliensnev) /* Elküldjük az üzenetet a kliensnek */ Rc = netbios('Send', 0, lsn, string) if string = 'QUIT' then leave if Rc = 0 then /* sikerült */ do /* Várjuk a kliens válaszát */ Rc = netbios('Receive', 0, lsn, 1000, 'data.') if Rc = 0 then /* megjött */ say data.0 else say 'A 'space(Kliensnev)' nem válaszol (Rc = 'Rc').' end else say 'A küldés sikertelen volt (Rc = 'Rc').' end /* forever */ /* Bezárjuk a szekciót */ call netbios 'Hangup', 0, lsn end else say 'A 'space(Kliensnev)' nincs a vonalban!!!' /* Visszaadjuk a lefoglalt Netbios erôforrásokat */ call netbios 'Close', 0 end else say 'A kért Netbios erôforrások nem elérhetôek (Rc = 'Rc').' exit
A bemutatott két program kiválóan alkalmas arra, hogy üzeneteket továbbítsunk olyan gépek között, amelyeken telepítve van a NetBios protokoll és a hálózaton keresztül össze vannak kapcsolva. A programok módosításával azt is elérhetjük, hogy a TCP/IP protokollal mûködô talk program NetBios protokollt beszélô változatát állítsuk elô.
REXX GYÍK:
K1. Nem futnak gépemen a megadott példaprogramok, mert indítás után a következô üzenetet kapom:
A Netbios erôforrások lefoglalása folyamatban... 12 +++ rc = netbios('Reset', 0, 1, 1, 1); REX0043: Error 43 running lecke02b.cmd, line 12: Routine not found
V1. Valószínûleg nincs a gépen telepítve a NetBios protokoll, ezért nem sikerül a netbios függvény regisztrálása. A NetBios protokollt az MPTS programban lehet telepíteni.
Gyakorlatok:
1. Írja át a fenti példaprogramokat oly módon, hogy a hívó és a hívott felek nevét a parancssorban lehessen megadni!
2. Írja át a fenti példaprogramokat oly módon, hogy mindkettô képes legyen üzenetek fogadására és küldésére (magyarul készítsünk talk programot)!
Kádár Zsolt 1998. 12. 12. |