Ebben a feladatban egy számítógépes hálózat szimulációjának egyszerűsített implementációját kell elkészítenünk. A részfeladatok megoldása során ügyeljünk arra, hogy a megadottakon kívül egyetlen osztály se tartalmazzon más publikus metódust vagy adattagot! A megoldás minden osztályát tegyük a router
csomagba!
A megoldást egyetlen zip
állományként kell feltölteni, amely tartalmazza a csomagnak megfelelő könyvtárszerkezetben az összes forráskódot. A fordítás során létrejövő class
állományokat viszont nem szabad már mellékelni! A fordításhoz minimum a Java Standard Edition 7 használata kötelező.
A kész megoldást az innen letölthető class
fájllal lehet tesztelni. Ezt a lefordított class
fájlokkal a következő módon lehet futtatni:
$ java Test
A hálózaton összekapcsolt gépeket ún. IP-címekkel fogjuk azonosítani. Az IP-címeknek többféle szabványa is létezik, ezek közül mi most az IPv4-et fogjuk választani, ahol a címek négy, pontokkal elválaszott, 0 és 255 közti egész számból állnak, például 127.0.0.1
, 8.8.4.4
vagy 255.255.255.255
.
Ezeket az IP-címeket reprezentáljuk egy külön osztállyal! Az osztály tartalmazzon:
egy konstruktort, amely paraméterként kap egy egészekből álló tömböt, amely tartalmazza az IP-cím egyes komponenseit, és ennek elemeit szükség esetén másoljuk is át,
egy osztályszintű fromString()
metódust, amely egy, az IP-címek szöveges leírásának megfelelő, például "12.100.32.76"
String
értékekből előállít egy IPAddress
objektumot, (Segítségül: figyeljünk arra, hogy ha reguláris kifejezéseket használunk a megoldásban, akkor a pontot muszáj escape-elni a "\\."
alkalmazásával!)
egy logikai értékkel visszatérő isTheSame()
metódust, amely eldönti, hogy a paramétereként átadott, IP-címet ábrázoló objektum megegyezik az objektumban tárolt IP-címmel,
egy logikai értékkel visszatérő insideRng()
függvényt, amely eldönti, hogy az adott IP-cím a paraméterként megadott másik két cím közé esik-e. Akkor mondjuk, hogy két cím közé esik egy harmadik, ha lexikografikus rendezés szerint az elsőtől nagyobb vagy egyenlő és a másodiktól kisebb vagy egyenlő.
Példák:
- 127.0.0.0 - 127.0.0.255 tartományon belül: 127.0.0.1
- 127.0.0.0 - 127.0.0.255 tartományon kívül: 10.0.0.1
- 0.0.0.1 - 63.127.127.127 tartományon belül: 23.0.0.0
- 0.0.0.1 - 63.127.127.127 tartományon kívül: 64.0.0.2
és egy String
visszatérési értékű toString()
metódust, amely formázott szövegként jeleníti meg az adott IP-címet. Ez formátum a korábbiak szerint négy, ponttal elválasztott számot fog jelenteni, például: "12.100.32.76"
.
A hálózaton utazó csomagokat reprezentáljuk a Packet
osztály egy objektumával! Egy ilyen Packet
típusú objektum tartalmazza a csomag által továbbított szöveges adatot, a csomag célpontját, a csomag által megtehető csomópontok felső korlátját (amely kezdetben legyen 50) és a csomag által meglátogatott csomópontok IP-címét! A felső korlátra azért lesz szükségünk, hogy a csomag, ha esetleg véletlenül hurokba kerülne, ne keringjen a végtelenségig a hálózaton.
A csomagokat leíró osztály tartalmazzon:
egy konstruktort, amely paraméterként megkapja az általa továbbítandó szöveges adatot és a célpont IP-címét,
egy getDestination()
metódust, amely a csomag célpontját segít lekérdezni,
egy recordPath()
nevű metódust, amellyel a csomag által bejárt IP-címek közé tudunk egy újabbat felvenni, ha azt ennek paraméterként megadjuk, valamint a recordPath()
hívása eggyel csökkenti a bejárható csomópontok felső korlátját. Viszont ha a bejárható csomópontok korlátját már eleve meghaladtuk, akkor ne is rögzítsük az IP-címet,
egy logikai értékkel visszatérő isLive()
metódust, amely el tudja dönteni, hogy az adott csomag továbbküldhető még, vagy már nem tehet meg több ugrást,
egy toString()
metódust, amely egy String
értékben szövegesen visszaadja a csomag által eddig bejárt IP-címek listáját és a hordozott üzenetet a következő formátumban:
kiindulási cím , IP-cím2 , ... , utolsó cím , üzenet
Például:
10.0.0.12 , 10.0.0.1 , 192.168.0.1 , 192.168.0.3 , ping
A számítógépes hálózat egy csomópontját a Node
osztály egy példánya fogja reprezentálni. A hálózaton minden egyes csomópont ismeri a szülőjét (megelőzőjét) és a gyermekeit (rákövetkezőit). Továbbá minden csomópont nyilvántartja a saját IP-címét és annak az IP-tartománynak a határait, amiért felelős.
Egy csomópontnak megfelelő Node
objektum létrehozása kétféle konstruktorral történhessen:
az az elem, amelynek van szülője, megkapja a szülőjét (mint csomópontot), a saját IP-címét, és a felelősségére bízott IP-címtartomány alsó és felső határát,
a gyökérelem pedig úgy jöhessen létre, hogy a paraméterek között a szülő csomópontot nem kell megadni!
A szimuláció során egy csomagot úgy fogunk továbbítani, hogy a csomópontokat leíró Node
osztályt kiegészítjük még egy tracePacket()
nevű metódussal. Ez a metódus egy csomagot kap paraméterként és a visszatérési érték egy String
objektum. A metódus működése legyen az alábbi:
ellenőrizzük, hogy a csomag céljának címe megegyezik-e a csomópont saját címével:
ha a csomópont címe egyezik a csomag célpontjával, akkor a csomag célbaért, ekkor a visszatérési érték legyen a csomag toString()
metódusa által előállított szöveg;
ha nem egyezik meg, akkor nézzük meg, hogy van-e olyan rákövetkezőnk, amely olyan IP-címtartományért felelős, amelybe a csomag célcíme tartozik, feltételezhetjük, hogy ezek a tartományok diszjunktak:
ha igen, akkor továbbítsuk az adott rákövetkezőnek a csomagot;
ha nem, akkor a továbbítsuk a megelőzőnknek a csomagot. Ha nincs a csomópontnak megelőzője (mert a hálózat gyökércsomópontjában vagyunk), akkor az eredmény legyen az "OUT"
szöveg.
Vegyük észre, hogy a csomagok továbbításában érintett csomópontoknak mindig meg kell hívnia a csomag recordPath()
metódusát. Illetve, a továbbküldés előtt mindig vizsgáljuk meg, hogy a csomag egyáltalán továbbküldhető-e! Ha ugyanis a csomópontok addig küldözgetnek egymásnak egy csomagot, amíg a megtehető, csomópontok közti ugrások felső korlátja nullára nem csökken, akkor a metódusnak "LOOP"
szöveggel kell visszatérnie!
Például:
Ebben a gráfban az alábbi lekérdezések a következő eredményeket adják:
// ...
Node n4 = new Node(n2, IPAddress.fromString("10.0.0.3"),
IPAddress.fromString("10.0.0.3"),
IPAddress.fromString("10.0.0.3"));
// ...
Packet p1 = new Packet("alma", IPAddress.fromString("192.168.0.5"));
System.out.println(n4.tracePacket(p1));
// "10.0.0.3 , 10.0.0.1 , 8.8.8.8 , 192.168.0.1 , 192.168.0.5 , alma"
Packet p2 = new Packet("alma", IPAddress.fromString("1.1.1.1"));
System.out.println(n4.tracePacket(p2));
// "OUT"
Packet p3 = new Packet("alma", IPAddress.fromString("10.0.0.2"));
System.out.println(n4.tracePacket(p3));
// "LOOP"
Jó munkát!