Programozási technológia 2.

Hasonló dokumentumok
Vé V g é r g e r h e a h j a tá t s á i s s z s ál á ak a Runnable, Thread

Concurrency in Swing

Az új be- és kimenet könyvtár

Java programozási nyelv 10. rész Input/output kezelés

URL-LEL ADOTT OBJEKTUM LETÖLTÉSE (1) URL-LEL ADOTT OBJEKTUM LETÖLTÉSE

Szoftvertechnológia alapjai Java előadások

Helyes-e az alábbi kódrészlet? int i = 1; i = i * 3 + 1; int j; j = i + 1; Nem. Igen. Hányféleképpen lehet Javaban megjegyzést írni?

C# Szálkezelés. Tóth Zsolt. Miskolci Egyetem. Tóth Zsolt (Miskolci Egyetem) C# Szálkezelés / 21

Ja J v a a v a há h l á óz ó a z t a i al a ka k l a maz ma á z s á o s k o Socket, URL

Kommunikáció Androidon Mobilinternet Wifi

Programozási nyelvek és módszerek Java Thread-ek

Hálózatkezelés. Tóth Zsolt. Miskolci Egyetem. Tóth Zsolt (Miskolci Egyetem) Hálózatkezelés / 20

CREATE TABLE student ( id int NOT NULL GENERATED ALWAYS AS IDENTITY PRIMARY KEY, name varchar(100) NOT NULL, address varchar(100) NOT NULL )

Széchenyi István Egyetem. Programozás III. Varjasi Norbert

Számítógépes Hálózatok. 5. gyakorlat

Segédanyag: Java alkalmazások gyakorlat

Programozási technológia

OOP: Java 8.Gy: Abstract osztályok, interfészek

Szerializáció. Tóth Zsolt. Miskolci Egyetem. Tóth Zsolt (Miskolci Egyetem) Szerializáció / 22

Segédanyag: Java alkalmazások gyakorlat

Java bevezet o Kab odi L aszl o Kab odi L aszl o Java bevezet o

Programozási technológia

Java Programozás 4. Gy: Java GUI. Tipper, MVC kalkulátor

Programozási nyelvek Java

Johanyák Zsolt Csaba: Ugráló gomb oktatási segédlet Copyright 2008 Johanyák Zsolt Csaba

Számítógépes Hálózatok. 7. gyakorlat

és az instanceof operátor

Java programozási nyelv

Java VIII. Az interfacei. és az instanceof operátor. Az interfészről általában. Interfészek JAVA-ban. Krizsán Zoltán

Java és web programozás

Osztályszintű elérés, kivételkezelés, fájlkezelés

Konkurens TCP Szerver

Se S r e ial a iza z t a ion o n (in n Ja J v a a v ) a Szerializáció

Debreceni Egyetem Informatika Kar. Mobiltelefon programozás és mobil adatbázis-kezelés

Osztályok. 4. gyakorlat

Kivételek kezelése (exception handling) Hibakezelés old style. Kivételkezelés

Java programozási nyelv 5. rész Osztályok III.

JAVA ALKALMAZÁSOK 5. ELŐADÁS 1/9/2017 1

Generikus osztályok, gyűjtemények és algoritmusok

Webes alkalmazások fejlesztése 8. előadás. Webszolgáltatások megvalósítása (ASP.NET WebAPI)

Web-fejlesztés NGM_IN002_1

Objektum Orientált Programozás. 11. Kivételkezelés 44/1B IT MAN

Enterprise JavaBeans. Ficsor Lajos Általános Informatikai Tanszék Miskolci Egyetem. Az Enterprise JavaBeans

Az osztályok csomagokba vannak rendezve, minden csomag tetszőleges. Könyvtárhierarhiát fed: Pl.: java/util/scanner.java

Hálózati architektúrák laborgyakorlat

3. Osztályok II. Programozás II

Programozási nyelvek Java

TCP/IP kapcsolat Java nyelven

Abstract osztályok és interface-ek. 7-dik gyakorlat

Programozási nyelvek Java

JAVA SE/ME tanfolyam tematika

List<String> l1 = new ArrayList<String>(); List<Object> l2 = l1; // error

Kommunikáció. 3. előadás

Java Programozás 11. Ea: MVC modell

OBJEKTUM ORIENTÁLT PROGRAMOZÁS JAVA NYELVEN. vizsgatételek

1. Gyakorlat: Telepítés: Windows Server 2008 R2 Enterprise, Core, Windows 7

PHP II. WEB technológiák. Tóth Zsolt. Miskolci Egyetem. Tóth Zsolt (Miskolci Egyetem) PHP II / 19

Beállítások 1. Töltse be a Planet_NET.pkt állományt a szimulációs programba! A teszthálózat már tartalmazza a vállalat

Programozási technológia

A Java nyelv IV. rész - appletek, hálózati alkalmazások fejlesztése

A gyakorlat során az alábbi ábrán látható négy entitáshoz kapcsolódó adatbevitelt fogjuk megoldani.

Enterprise JavaBeans 1.4 platform (EJB 2.0)

Ugráló gomb oktatási segédlet Ugráló gomb

JNDI - alapok. Java Naming and Directory Interface

Számítógépes Hálózatok GY 4.hét

4. Hivatkozási modellek

Kivételkezelés, beágyazott osztályok. Nyolcadik gyakorlat

Java Programozás 6. Gy: Java alapok. Adatkezelő 2.rész

OOP #14 (referencia-elv)

Programozási technológia 2.

applikációs protokollok

Java II. I A Java programozási nyelv alapelemei

Számítógépes Hálózatok GY 7.hét

JavaServer Pages (JSP) (folytatás)

Java Programozás 1. Gy: Java alapok. Ismétlés ++

C#, OOP. Osztályok tervezése C#-ban

Alap protokollok. NetBT: NetBIOS over TCP/IP: Name, Datagram és Session szolgáltatás.

Bevezető. PoC kit felépítése. NX appliance. SPAN-Proxy

Két típusú összeköttetés PVC Permanent Virtual Circuits Szolgáltató hozza létre Operátor manuálisan hozza létre a végpontok között (PVI,PCI)

Multiprotocol encapsulation (RFC1483) - IETF Classical IP over ATM (RFC1577) - IETF LAN Emulation (LANE) - ATM Forum Multiprotocol over ATM (MPOA) -

Számítógépes Hálózatok. 3. gyakorlat

OOP: Java 8.Gy: Gyakorlás

Java programozási nyelv 4. rész Osztályok II.

Alkalmazás rétegbeli protokollok:

Hálózati architektúrák és Protokollok GI Kocsis Gergely

OOP és UML Áttekintés

Számítástechnika II. BMEKOKAA Előadás. Dr. Bécsi Tamás

Fábián Zoltán Hálózatok elmélet

Számítógépes Hálózatok. 4. gyakorlat

WEBFEJLESZTÉS 2. ADATBÁZIS-KEZELÉS, OSZTÁLYOK

Szoftvertechnolo gia gyakorlat

Számítástechnika II. BMEKOKAA Előadás. Dr. Bécsi Tamás

Kommunikáció - Wi-Fi, Mobil internet - Bluetooth - GSM / GPRS és SMS - NFC

Tartalom DCOM. Történeti áttekintés. Történeti áttekintés. Történeti áttekintés. Történeti áttekintés

Osztálytervezés és implementációs ajánlások

A Wireshark program használata Capture Analyze Capture Analyze Capture Options Interface

Osztálytervezés és implementációs ajánlások

Számítógépes Hálózatok GY 6.hét

Számítógépes hálózatok

UNIX: folyamatok kommunikációja

Átírás:

Programozási technológia 2. Dr. Szendrei Rudolf ELTE Informatikai Kar 2018.

PacMan Készítsünk egy szellem mentes két személyes PacMan játékot Ha a játékosok PacMan-jei mindent megettek, a játék újraindul Alkalmazzunk MV architektúrát 2

PacMan modell A játék egy személyes implementációját a korábbi félév alapján már el tudjuk készíteni MV architektúrában A két személyes módhoz egy helyett két PacMan-t tárolunk el a modellben. A játékosokhoz a W,A,S,D és a,,, gombokat rendeljük. A modellben két fő osztály jelenik meg Player Tárolja egy PacMan nézési, mozgási, kanyarodási irányát, a pozícióját és a színét GameBoard Tárolja a pálya állapotát, a két PacMan példányt, és megvalósítja a logikát 3

PacMan modell GameBoard logika fő részei changeplayerdirection(int player, Direction d){ Eltárolja a megadott játékos PacMan-jéhez a mozgási irány szándékát a saját PacMan példányban moveplayers() { A View időzítője által periodikusan hívott metódus adott egységgel elmozdítja a PacMan-eket, amennyiben nem ütköznek falba mozgatás közben animálja PacMan száját eltávolítja a pályáról a megevett falatokat 4

PacMan több személyes mód Alakítsuk úgy át a játékot, hogy a két személy internet hálózaton keresztül tudjon együtt játszani. Mivel a hálózatos programokban a hibákat jóval nehezebb felderíteni, ezért a fejlesztést több lépcsőben hajtjuk végre. 1. Modell állapotonák mentése / visszatöltése 2. Tesztelés 3. Modell származtatása vékony kliens / szerver szerepekhez 4. Tesztelés 5. A modellek hálózatos változatának létrehozása 6. Tesztelés 5

PacMan vékony kliens architektúra A vékony kliens lényege, hogy csak megjelenítőként funkcionál, a felhasználói interakciókat a szerverhez továbbítja. A szerver minden információval rendelkezik, megvalósítja a logikát, a klienseknek pedig csak a megjelenítéshez szükséges adatokat küldi át. 6

Adatok reprezentációja Vezessük be a Player és GameBoard osztályokban az állapot mentésére / visszatöltésére szolgáló metódusokat. A Serializable interfész használata túlságosan költséges, pl. a Player osztályt 582 bájttal képes csak reprezentálni. A Player osztály kliensben megjelenítendő állapotához 6 bájt is elegendő: 1 Byte - nézés iránya (facedir), 2x2 Byte - pozíció (smoothpos), 1 Byte - száj nyitottsága 7

PacMan Player osztály állapot mentés / betöltés public byte[] tobytearray(){ ByteBuffer bb = ByteBuffer.allocate(representationSize); bb.putshort((short)smoothpos.x); bb.putshort((short)smoothpos.y); bb.put((byte)mouth); bb.put((byte)facedir.ordinal()); return bb.array(); // length = 6 bytes public void updatefromstream(inputstream is) throws IOException { DataInputStream dis = new DataInputStream(is); int sx = dis.readshort(); int sy = dis.readshort(); pos.setlocation(sx / scale, sy / scale); scaledpos.setlocation(pos.x * scale, pos.y * scale); smoothpos.setlocation(sx, sy); this.mouth = dis.readbyte(); this.facedir = Direction.values()[dis.readByte()]; 8

PacMan GameBoard osztály állapot mentés public byte[] tobytearray() { int numbytes = width * height + players.size() * Player.representationSize; ByteBuffer bb = ByteBuffer.allocate(numBytes); for (int i = 0; i < players.size(); i++){ bb.put(players.get(i).tobytearray()); for (int y = 0; y < height; y++){ for (int x = 0; x < width; x++){ // mark the differences bb.put((byte)((table[y][x]!= origtable[y][x])? 1 : 0)); return bb.array(); 9

PacMan GameBoard osztály állapot betöltés public final synchronized void frombytearray(byte[] array){ if (array == null array.length!= representationsize) return; ByteArrayInputStream bais = new ByteArrayInputStream(array); try { for (int i = 0; i < players.size(); i++){ players.get(i).updatefromstream(bais); int byteindex = players.size() * Player.representationSize; for (int y = 0; y < height; y++){ for (int x = 0; x < width; x++){ if (array[byteindex++] > 0){ table[y][x] = Item.EMPTY; catch (IOException e){ 10

PacMan Tesztelés Az elkészített mentés / visszatöltés metódus párokhoz készítsünk egységteszteket! 11

PacMan Kliens / szerver modellek Az elkészített szerializációs metódusokat a kliens/szerver modell a következőképpen fogja alkalmazni Szerver Kliens Player Player tobytearray() GameBoardServer tobytearray() changeplayerdirection() frombytearray() updatefromstream() GameBoardClient 12

PacMan Kliens / szerver modellek Mivel a játék logika a szerverben valósul meg, ezért a kliens képernyőjének frissítése nem egy saját időzítőtől, hanem a szervertől kapott jelzésektől fog függni. A fentiek miatt elengedhetetlen, hogy a kliens egy külön szálat futtasson a beérkező adatokra való várakozáshoz és feldolgozáshoz. A hálózati kommunikáció a szervernél is külön szálat igényel, az ok viszont ebben az esetben a reakció idő minimalizálása. a A kapott utasításokat így nem periodikusan dolgozzuk fel (időzítőre alapulva), hanem egy külön szálon azonnal. A modelleket a GameBoard osztályból fogjuk származtatni, azonban a szálkezeléssel kapcsolatos közös részeket egy köztes GameBoardThreading leszármazottba helyezzük. A klienseket és a szervert először csak csővezetékkel (Pipe) fogjuk összekötni, hogy teszteljük a módszer helyességét... 13

PacMan Kliens / szerver modellek GameBoard + void changeplayerdirection(int player, Direction d) + void moveplayers() + byte[] tobytearray() + void frombytearray(byte[] array) ClientDisplay <<interface>> void refresh() void connectionlost() void cannotconnect() GameBoardThreading + void start() + void stop() - void run() # void logic() ServerDisplay <<interface>> void connectionlost(int client) void cannotopenserver() void allclientsareconnected() GameBoardClient # void logic() + void changeplayerdirection(direction d) + void moveplayers() GameBoardServer # void logic() + void setdisplay(serverdisplay display) + void connectionlost(int client) + void cannotopenserver() + void allclientsareconnected() 14

Szálkezelés emlékeztető Védeni kell azon erőforrásokat, melyeket legalább egy szál módosítani tudna úgy, hogy közben egy másik hozzáférhet. Ökölszabályok A megoldáshoz kell egy obj objektum, aminek a synchronized(obj){ blokkjában a hozzáférés történik. Ez lehet maga a védendő erőforrás is Durva megoldás: synchronized(this){ a metódusban vagy synchronized metódus, ami állapotot olvas/módosít Az objektum minden írható attribútuma legyen privát. Az objektum típusú attribútumnak a referenciája helyett az objektum másolatát adja vissza a synchronized metódus. 15

PacMan GameBoardThreading public abstract class GameBoardThreading extends GameBoard implements Runnable{ private volatile Thread thread; private volatile boolean isrunning = false; private final String name; public GameBoardThreading(String name){ this.name = name; public synchronized void start() {... public synchronized void stop() {... @Override public void run() {... protected abstract void logic(); 16

PacMan GameBoardThreading public abstract class GameBoardThreading extends GameBoard implements Runnable{ public synchronized void start(){ if (!isrunning){ isrunning = true; thread = new Thread(this); thread.start(); public synchronized void stop(){ if (isrunning){ thread.interrupt(); while (isrunning){ try { wait(); catch (InterruptedException ex) { 17

PacMan GameBoardThreading public abstract class GameBoardThreading extends GameBoard implements Runnable{ @Override public void run() { logic(); synchronized (GameBoardThreading.this){ isrunning = false; notifyall(); System.out.println(name + ": stopped"); 18

Kliens / szerver kapcsolat A kapcsolatot a két oldalon InputStream / Outputstream reprezentálja majd, ezért már most figyeljünk a következőkre! Ha nincs elegendő adat a bemeneten, akkor az olvasás blokkolja a szálat! A blokkolt szál nem szakítható meg, és nem érzékeli az olvasás hiányának okát! Nem blokkoló megoldáshoz bájt tömböket kell használnunk, melyekbe annyit olvasunk, amennyit éppen lehet. Ha rendelkezésre áll a kellő adat, csak akkor dolgozzuk fel. A bájt tömböt a ByteArrayInputStream segítségével InputStream-ként dolgozhatjuk fel. Más adattípusokhoz (int, float, double...) létrehozhatunk a szokásos módon DataInputStream-et is belőle. 19

Adatkapcsolat megszűnésének érzékelése OutputStream Az írási kísérlet IOException-t vált ki. InputStream Olvasáskor nem tudhatjuk, hogy a másik fél elveszett, vagy csak nincs közlendője. Egy jó megoldás, ha a másik féltől elvárjuk, hogy adott időközönként üzenjen (Ping), így a kapcsolat tétlensége elárulja a kapcsolat megszűntét. Az InputStream egyedüli nem blokkoló metódusa az available() Visszatérési értéke jelzi, hogy a fogadó buffere üres-e. A blokkoló read(byte[] buf, int pos, int len) metódussal csak ebben az esetben olvasunk, amennyit éppen lehet. Ha összegyűjtöttük a szükséges adatokat, akkor feldolgozzuk. 20

PacMan GameBoardServer Konstruktor Input-/OutputStream tömbben kapja meg a klienseihez tartozó kapcsolatokat logic() Ciklusa addig fut, amíg a szál nem kerül megszakított állapotba. A ciklus minden iterációjában Olvas a klienseihez tartozó bemenetekről ha tud, majd ez alapján hívja a changeplayerdirection(...) metódusát Eltávolítja azokat a klienseket, amelyek eltűntek Meghívja a moveplayers() metódust a játék léptetéséhez Előállítja a modell bájt reprezentációját a tobytearray() segítségével, és elküldi azt valamennyi kliensének Várakozik a beállított frissítési gyakoriságnak megfelelően 21

PacMan GameBoardClient Konstruktor InputStream / OutputStream paramétere a kapcsolatot reprezentálja. changeplayerdirection(direction d) A felhasználói interakciókat kiküldi az OutputStream-re. moveplayers() logika híján üres. logic() Ciklusa addig fut, amíg a szál nem kerül megszakított állapotba. A ciklus minden iterációjában vár egy újabb csomagot, amivel frissíti a modellt (ilyenkor a kinézetet is frissíti). Adat hiányában számolja a kapcsolat tétlenségének idejét, és jelzi, ha a kapcsolatot megszakadtnak tekinti. 22

PacMan A kliens és a szerver tesztelése A klienst és a szervert először hálózati kapcsolat használata nélkül implementáltuk, hogy lássuk működnek-e. Ahhoz, hogy a kapcsolatukat tesztelhessük, minden egyes kliens esetében a következőt kell tennünk Kössük össze a kliens OutputStream-jét a szervernek a klienshez tartozó InputStream-jével. Kössük össze a kliens InputStream-jét a szervernek a klienshez tartozó OutputStream-jével. Két kliens esetén a fentiek alapján 4 db egy irányú kapcsolatot kell kapnunk. Java-ban ehhez a PipedInputStream, PipedOutputStream használható, melyek közvetlenül összeköthetőek, egy csővezetéket létrehozva. 23

Pipe Adatfolyamok Dekorátor osztály alaptípusokhoz OutputStream DataOutputStream FileOutputStream ByteArrayOutputStream PipedOutputStream File Byte Array FileInputStream ByteArrayInputStream PipedInputStream Dekorátor osztály alaptípusokhoz DataInputStream InputStream 24

PacMan A kliens és a szerver tesztelése PipedInputStream[] client_in = new PipedInputStream[2]; PipedInputStream[] server_in = new PipedInputStream[2]; PipedOutputStream[] client_out = new PipedOutputStream[2]; PipedOutputStream[] server_out = new PipedOutputStream[2]; GameBoardClient[] clients = new GameBoardClient[2]; for (int i = 0; i < 2; i++){ client_in[i] = new PipedInputStream(); client_out[i] = new PipedOutputStream(); server_in[i] = new PipedInputStream(client_out[i]); server_out[i] = new PipedOutputStream(client_in[i]); GameBoardServer server = new GameBoardServer(200, server_in, server_out); server.start(); // Clients has to start AFTER the server is started, otherwise their // constructor will block on their InputStream for (int i = 0; i < 2; i++){ clients[i] = new GameBoardClient(client_in[i], client_out[i], null); clients[i].start(); clients[0].changeplayerdirection(direction.up);... server.stop(); clients[0].stop(); clients[1].stop(); 25

PacMan Hálózati kapcsolat megvalósítása Az előző programfázisok sikeres tesztjei után most bővítsük ki a játékot úgy, hogy hálózatban is lehessen vele játszani. Tekintsük át először a hálózati kapcsolat alapfogalmait 26

Alapok InternetProtocol A hálózati kommunikációban résztvevő eszközöket az IP címük azonosítja (IPv4 vagy IPv6) Az IP (Internet Protocol) a forgalomirányításért felelős protokoll Egy eszközt több IP cím is azonosíthat Önmagára hivatkozás: 127.0.0.1 (localhost, mindig létezik) Internetes IP cím(ek) Az eszközön futó szolgáltatásokat a port szám azonosítja Például: HTTP: port 80 HTTPS: port 443 SSH: port 22 27

Alapok adatátviteli protokollok A kommunikáció módja függ az alkalmazott protokolltól, például TCP Transfer Control Protocol 1-1 kapcsolat, ami a kliens-szerver modellt implementálja Kétirányú Megbízható adatátvitel UDP Unified Datagram Protocol Unicast egy címzett Multicast, Broadcast több címzett Egy irányú Megbízhatatlan adatátvitel Gyors kézbesítés 28

Alapok TCP / IP kapcsolat Egy virtuális csővezeték, amit a két végpontja azonosít. A végpontot az (IP cím, port) páros azonosítja. A csomagról mindig ismert a forrás és cél IP címe, port száma. A 0..1023 port tartomány a szabvány szerinti szolgáltatásoknak fenntartott (pl. 53 DNS, 80 HTTP stb.). IP A cím IP B cím Kliens Alkalmazás Socket Port A Operációs rendszer TCP/IP kapcsolat [ IP A : Port A IP B : Port B ] Internet Szerver Alkalmazás Socket Port B Operációs rendszer 29

Alapok TCP / IP kapcsolat felépítése Szerver alkalmazás Egy általa választott, rá jellemző számú portot nyit, és ezen várja a kliensek kapcsolódását. Kliens alkalmazás Az operációs rendszer segítségével kapcsolatot kezdeményez a szerverrel, annak IP cím és a port megadásával. A kapcsolathoz az operációs rendszer oszt tetszőleges portot. 30

Hálózati kapcsolat Java-ban A socket az adatcsatorna szoftveres végpontja. Amit beleírunk, az megjelenik a másik oldalon. Java-ban a Socket-hez InputStream / OutputStream páros tartozik. Connect Connect Socket Internet Socket Connect InputStream OutputStream InputStream OutputStream Client program ServerSocket Listen & Accept Server program 31

Hálózati kapcsolat Java-ban Java-ban két fajta Socket-et használunk Socket Az adatátvitel megvalósítására használható végpont, mind a kliens, mind pedig a szerver oldalon. ServerSocket Figyeli a csatlakozási kéréseket Adatátvitelben nem vesz részt Csatlakozáskor az új kapcsolathoz új Socket-et készít Érdemes beállítani a hálózati műveletekhez lejárati időt a setsotimeout(int ms) metódussal. Így, ha nem történik semmi ezen időn belül, akkor SocketTimeoutException-t kapunk. Szálkezelés esetén a megszakíthatóságot garantálhatjuk vele. 32

PacMan Hálózatos kliens / szerver modellek Az előbbi információk birtokában készíthetünk egy a GameBoardClient / GameBoardServer-hez hasonló párost GameBoardNetClient A megadott IP cím (vagy domain név) és port alapján kapcsolódik a szerverhez, majd a GameBoardClient-ben látottaknak megfelelően működik tovább. GameBoardNetServer A megadott számú portot megnyitja, majd megvárja amíg az összes kliens kapcsolódik. Eközben már küld Ping jelzéseket (jelen esetben a modell bájt reprezentációját). A továbbiakban pontosan ugyanazt cselekszi, mint a GameBoardServer. 33

PacMan Hálózatos kliens / szerver modellek GameBoard + void changeplayerdirection(int player, Direction d) + void moveplayers() + byte[] tobytearray() + void frombytearray(byte[] array) ClientDisplay <<interface>> void refresh() void connectionlost() void cannotconnect() GameBoardThreading + void start() + void stop() - void run() # void logic() ServerDisplay <<interface>> void connectionlost(int client) void cannotopenserver() void allclientsareconnected() GameBoardNetClient # void logic() + void changeplayerdirection(direction d) + void moveplayers() GameBoardNetServer # void logic() + void setdisplay(serverdisplay display) + void connectionlost(int client) + void cannotopenserver() + void allclientsareconnected() 34

Tipp hálózatos alkalmazásokhoz Érdemes a ping -et a valós adattól megkülönböztetni. Ennek legegyszerűbb módja, ha a küldött adat első bájtja (int-je) meghatározza az adat típusát / célját (ping, frissítés ) Ez alapján tudhatjuk, hogy él-e a kapcsolat, és milyen típusú és mennyi adatot kell olvasni és feldolgozni. Példa A kliensek az összes kliens kapcsolódásáig csak ping-eket kapnak, így látják, hogy a kapcsolat él, de a játék nem indult el. Hálózatos tesztelést gyakran végzünk egy gépen több futó alkalmazás példánnyal. Nehézség, hogy a billentyű és egér eseményeket a JRE csak az aktív ablaknak továbbítja. Ennek áthidalására a JNativeHook könyvtár használható. 35