Java proxy

 

Ki ne gondolt volna már arra, hogy ma megvásárolt számítógépét a régivel összekösse, hiszen a régit sem eladni nem tudta, sem pedig kidobni nem akarta. Mivel a hálózatok korát éljük, könnyen előfordulhat az is, hogy az újító ember rendelkezik internet kapcsolattal, és szeretné, hogy mindkét számítógépén böngészője képes legyen kapcsolatba lépni az internettel, de valahogy az előírt próbálkozásaival mindeddig nem tudta elérni célját, és arra kényszerült, hogy letöltött, kisebb programokkal kísérelje meg a kapcsolatmegosztást létrehozni.

 

A probléma tehát adott, így programunkkal megkísérelünk egy megoldást produkálni. A program egyetlen klienssel lett tesztelve. A szerver egyetlen portra, a 8080-ra figyel, és a kommunikációs partner címét nem kérdezem le, következésképpen ez egy kétgépes alkalmazás. Az JDK-át annak rendje és módja szerint kell telepíteni a futtatáshoz, valamint a szokásos környezeti változóknak értéket kell adni. A programot a jdk1.3.0_02 változatával állítottam elő, és fordítottam. Az internet beállításoknál a böngésző portját 8080-ra kell állítani, ha lehet még a szerver IP címét is meg kell adni, a szervert el kell indítani, és láss csodát, a kapcsolat működni kezd.

A jávában a hálózati kapcsolat vagy a TCP protokollt használja,  vagyis úgynevezett összeköttetés-alapú, vagy pedig összeköttetés mentes, amikor az UDP protokollra épül. Az utóbbi kezelése meglehetősen nehézkes, ezért az TCP kapcsolat látszik célszerűnek. A TCP-ét kezelő osztályokkal dolgozom a továbbiakban. A legfontosabb osztályok a Socket, és a ServerSocket. Az utóbbi egy szerverobjektum osztálya lehet, amelynek accept metódusa képes a konstruktorral megadott porton figyelni. Visszaad egy Socket osztályú példányt, amellyel azonosítani lehet a ki-, beviteli adatcsatornát (Input-,OutputStream) , és a kommunikációt le lehet folytatni.

A program négy osztályból áll. A GV osztály tárolja a statikus, publikus változókat, amelyek a fordítási egység bármely pontjáról elérhetőek. Mondhatnám az is, a globális változókról van szó. A változók között van például az input, output csatornákhoz szükséges kódolás azonosítója, amely jelen esetben ISO Latin2 (8859_2).

Az indításért a DProxy felelős, amely a kezdeti értékek beállítása után két szálat indít el. A szerver szálai közül az egyik figyeli a 8080-as portot, amely ha kérést fogad, azt letárolja egy tömbben. Ebben a tömbben folyamatosan felírásra kerülnek a kérések. A tömb, mintegy végtelenített, mert ha betelik, és az elején már nincs tárolt objektum, az első elemtől kezdi újra a feltöltést.

A másik szál feladata pedig pont az, hogy a tárolt kéréseket feldolgozza. Sorban kiveszi a Socket objektumokat, azokból egy bemeneti adatfolyamot nyer ki, és így képes a port egyik kérését olvasni. A kliens továbbítja a kérést fejléc formájában, amelyet a hálózaton keresztül szövegesen lehet olvasni. Erre szolgál a readLine metódus. A kérés első sora a "GET http://"... paranccsal kezdődik, amely a lekérni kívánt oldal URL azonosítója, majd ezt követik a fejlécmezők és értékeik, ahogyan azt a MIME-szabványban specifikálták. A MIME HTTP alapú kapcsolatnál a szerver és a kliens közötti információk átvitelére szolgál. A következő rész célja, hogy megnyissa az URL kapcsolatot, és a kérést a setRequestPropery metódus segítségével maradéktalanul átadja, amely a HttpUrlConnection nevű, HTTP protokoll alapú erőforrások elérésére specializált osztály feladata.

Az URL objektum tartalmához szintén egy adatfolyamot rendelek hoz zá, majd előzőleg az output néven létrehozott kimeneti csatornába visszaírom a választ kapcsolatot létesítve a klienssel. Semmi más teendő nincs, mint a kérést maradéktalanul átadni, a többi már a Stream-ek feladata. Nem véletlenül adom át, és olvasom be karakterenként az adatokat, mert csak így működött helyesen. Nem jelent a sebesség problémát még így sem. Nálam a szerver egy 333Mhz , a kliens pedig egy 2GHz sebességű számítógép volt. A végén le kell zárni a portot, illetve az adatfolyamokat.

Az első alkalommal az esetek 1%-ban nem mindig sikerült az adott objektumot letölteni a hálóról és "download failed" üzenet jelent meg. Képek letöltése esetén tapasztaltam. Megpróbálhatnák egy második kísérletet is, hiszen az IO kivétellel lekezelhető, de ezt már az olvasóra bízom. Még egy fontos dologról nem szóltam. Mivel a program a proxy nevet kapta, ezért elengedhetetlen az események naplózása. Bárki hozzáláthat, hogy a program ne a képernyőre, hanem egy állományba írja a lekért objektumok URL hivatkozását. Nem esett szó a biztonságról. A java interpretált mivolta tulajdonképp garancia arra, hogy ne történjék valamilyen biztonságból eredő hiba, node vannak kivételek. Mint tudjuk a kisördög nem alszik, tehát ebből az okból a programmal kapcsolatos semmilyen felelősséget nem vállalunk.

 

Dunás-Varga Zsolt - dproxy@freemail.hu