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. |