Tartalom:
- Grid
- Cloud
- infomrációs rendszerek
A
hardware -> Interface -> Hardware/software system
átalakítjaprogram -> Interface A -> Implementation of mimicking A on B -> Interface B -> Hardware/software system B
alakká.
- Application
- Library functions
- Operating system, sys calls
- Hardware -> general instructions,Prvileged instructions
JAVA
minden bytcode egy "mini program", a runtimeban van futtatva:
- Application
- Runtime sys
- Operating system
- Hardware
VMware, VirtualBox
- Applications
- Operating system
- Virtual machine monitor
- Hardware
Előnyei a JAVA féle megoldáshoz képest:
A teljes
Application
ésOS
réteget egy teljesen újgép
re viheti át. Ekkor aVM Monitor
egy operációs rendszer! Azaz nagyon egszerű rendszerekkel rendelkezik, a minimális driverekkel és hasonlókkal, de egy teljes OS tulajdonságaival ugyankkor a minimális tulajdonságokkal amik a feladat végrehajtásához szükségesek.Tehát közvelten a hardwaerhez van útja a az
App
ésOS
rétegnek, hiszen aVM
közbvetlen a hardwaret szólítja meg.
a lényege, hogy az egyiket a processzor szintjén hozzuk létre, a másikat pedig a programnak kiosztott erőforrásokban hozzuk létre
Olyan program ami felhasználó interakciói nélkül nem műödne, pl MS-Excel, bővebben
Az
IP
t kiosztóhome server
újrahosztol
anycast
- továbbítja a hozzá kapcsolódó routereknek a csomagot
changeroute
- az olvasási pontot átteszi máshova
Kliens oldal
az interface a paraméterekt becsomagolva elküldi a szervernek
Szerver oldal
megkapja a paramétereket, ugyanazzal a paraméterrel és meghívja az azonos paraméterezésű, azonos nevű progamot
middleware szempontból csak a szerveren a kicsomagols és újraparaméterezés az érdekes
Részletesen:
- a kliens eljárás meghívja a csatolót
- a csatoló létrehozza az üzenetet, meghívja a kliens OSét a csatoló egy olyan kódrészlet ami átalakítja a bemeneti kódot a szálításhoz és az OS hívásokhoz
- a kliens OS elküldi az üzenetet a távoli gép OSére
- a távoli gép OSe megkapja az üznet és a helyi csatolónak átadja
- a távoli gépen kicsomagolódik az üzenet és meghívvja a megszólított szervert
- a szerver elvégzí a szükséges hívásokat és visszatér a kért értékkel
- a távoli gép OSének csatolójával becsomagolódik a szerver válasza
- a távoli gép OSe elküldi a kliens OSnek
- a kliens OS megkapja, és átadja kicsomagolásra a csatolónak
- kicsomagolódik a válasz a kliensnél és átadja a kliens függvénynek ami a hívást kezdeményezte
Ilyenkor a httérben a szerver és a kliens egy "közös" headert használnak, de a gnerált kód külön-külön a szerveren és a kliensen jelenik meg a helyi (klines/szerver) linkeren keresztül, et a DCE
Tehát ez olyan, mintha egy köztes gép lenne, ami a szükséges fájlokat tárolja, amikre mindkét oldalnak szükésge van, de gy ilyen felállásban ha a köztes szerver ami a headereket tárolja(Directory server) meghal akkor a rendszer is használhatatlan az új kliensek számára, a régieknél már be van linkelve a szükséges fájl. Részletese menete:
- Register server endpoint
- register service from Direcotry server to server
- Client look up for directory server
- Client ask for server's endpoint
- Clinet do
RPC
ccollections of brokers in a network and let to route the msg to broker to broker
don't thell to the broker what the msssg is about and the broke find it out
ssometimes is more complicated
- személyes felhő, megy rpi-n is
- számítási kapacitást visz át, elosztott rendszerekbe, ahol bucketeekben dolgoznak a felhasználók
- Cloud downloader, Bit Torrent client, media player, preview and play while download
- connect to different torrent search engine
- megkeresi a bit torent index fájlt a fájlszerveren (Pirate Bay)
- tovább meg a trackerhez a
.torent
fájlban talált pointer alapján - a tracker megmondja, hogy kinek lehet meg az adott rész, nem pontosan, csak lehetőségként, úgy, hogy az aki keresi annak meglegyen az ami a másiknál hiányzik
- magnet linkek egy P2P rendszerre mutató pointerek
- VM teszteléshez
- egy elosztott szerverkutatóhálózatok között
- egész féléves előadás anyaga egyben
- securityval kapcsolatos fájlok, előadások
- Maarten van Steen könyv
mintafájlok: gy1/ElsoSzerver.java | gy1/ElsoKliens.java | gy1/Szerver2.java
- Első lépésben elindítjuk egy
PORT
-on aServerSocket
segítségével:ServerSocket ss = new ServerSocket(PORT);
- Várunk a kliens megjelenésére:
Socket s = ss.accept();
FIGYELEM! Ez akár évekig is hajlandó várni, amíg a kliens meg nem jelenik, vagy a programot ki nem kapcsoljuk! - A szerverre bejövő információkat
Scanner
segítségével kapjuk el:Scanner sc = new Scanner(s.getInputStream());
- A szerveren kimenőket meg
PrintWriter
el küldjük ki:PrintWriter pw = new PrintWriter(s.getOutputStream());
teljes kód:
import java.io.*;
import java.util.*;
import java.net.*;
public class ElsoSzerver {
public static void main(String[] args) throws Exception {
int PORT = 12345;
try (
ServerSocket ss = new ServerSocket(PORT);
Socket s = ss.accept();
Scanner sc = new Scanner(s.getInputStream());
PrintWriter pw = new PrintWriter(s.getOutputStream());
) {
String name = sc.nextLine();
pw.println("Hello, " + name);
pw.flush();
}
}
}
Kliensként ilyenkor felcsatlakozhatunk PuTTY-al is akár: Hostname: localhost
; Port: 12345
; Connection type: Raw
; Close window on exit: Never
beállításokkal.
De írhatunk sajátot is:
- Először adjuk meg hova szeretnénk kapcsolódni:
String MACHINE = "localhost";
itt a"localhost"
ot akár lecserélhetjük egy IPra is:"127.0.0.1"
- Adjuk meg a
PORT
ot:int PORT = 12345;
- Kapcsolódjunk:
Socket s = new Socket(MACHINE, PORT);
- A kliensre bejövő adatfolyamra várjunk egy
Scanner
segíségével:Scanner sc = new Scanner(s.getInputStream());
- A kliensnél kiemenő adatokat a szokásos
PrintWriter
segítségével oldhatjuk meg:PrintWriter pw = new PrintWriter(s.getOutputStream());
De vigyázzunk a használatával, ugyanis, minden kiíratás utánflush
ölni kell amit írtunk. Ez küldi el a szervernek, ha egymás után több dolgot kiíratunk aPrintWriter
re és utánnaflush
ölünk akkor egybe fog lemenni az egész, nem soronként! Azaz így:pw.println("AzEnNevem"); pw.flush();
teljes kód:
import java.io.*;
import java.util.*;
import java.net.*;
public class ElsoKliens {
public static void main(String[] args) throws Exception {
String MACHINE = "localhost";
int PORT = 12345;
try (
Socket s = new Socket(MACHINE, PORT);
Scanner sc = new Scanner(s.getInputStream());
PrintWriter pw = new PrintWriter(s.getOutputStream());
) {
pw.println("AzEnNevem");
pw.flush();
String valasz = sc.nextLine();
System.out.println(valasz);
}
}
}
Scanner
nél hasznosak lehetnek:
sc.hasNextLine()
- várja következő sort vagy a halott servert
sc.hasNext()
- átugorja az összes whitespacet
sc.hasNextInt()
- átugorja a whitespaceket és számot vár válaszként
eredeti: gyak2
fájlok: gy2/Szerver3.java - mintafájl-0ra lép ki | gy2/server.java - saját megoldás-karakteres üzenetre lép ki
A kliens küldjön át sorban egész számokat a szervernek. A számokat a kliens egy fájlból olvassa be. A szerver mindegyik számra meghív egy függvényt, ami egész számot készít (mondjuk
n ↦ 2*n+1
), majd az eredményt visszaküldi a kliensnek. A kliens a visszakapott eredményeket egy fájlba írja ki sorban. Ha a0
szám következne a kliensoldalon, akkor a kliens kilép.
A kliens most küldje át az összes adatot a szervernek, és csak utána fogadja a visszaérkező számokat; hasonlóan, a szerver fogadja az összes számot, és csak utána küldje el őket átalakítva a kliensnek.
A szerver várakozzon a kliens kilépése után új kliensre, és ez ismétlődjön a végtelenségig.
Az érdekes rész a sorban egymás után végtelen sok klienst kiszolgáló szerver:
while (true){
try (
ServerSocket ss = new ServerSocket(PORT);
Socket s = ss.accept();
Scanner sc = new Scanner(s.getInputStream());
PrintWriter pw = new PrintWriter(s.getOutputStream());
) {
while(sc.hasNextInt()){
Integer nr = sc.nextInt(); //beérkezik az adat
tmp.add(toInt(nr)); //feldolgozás
}
answer(tmp, pw); //válasz
}
}
eredeti: gyak3
fájl: gy3/Szerver4.java
A kliens átküld egy fájlnevet a szervernek. A szerver küldje vissza a fájl tartalmát soronként, ha a fájl létezik, különben pedig egy szöveges hibaüzenetet. Lényeges rész:
static void simpleFtp(Scanner sc, PrintWriter pw) {
String filename = sc.nextLine();
try (Scanner scFile = new Scanner(new File(filename))) {
while (scFile.hasNextLine()) {
String line = scFile.nextLine();
pw.println(line);
}
} catch (IOException e) {
pw.println("Error: " + e);
} finally {
pw.flush();
}
}
eredeti: gyak4
fájl: gy4/Szerver8.java
Felmerülhet, hogy mi van agyszerre több klienst szeretnénk kezelni egy szerveren egy PORT
on. Megoldásként duplikálhatunk mindent, azaz:
- Létrehozzuk a
PORT
ot:int PORT = 12345;
és hallgatózunk rajta:ServerSocket ss = new ServerSocket(PORT);
- Figyelünk egy
Scanner
ésegyPrintwriter
rel, mint eddig:Socket s1 = ss.accept(); Scanner sc1 = new Scanner(s1.getInputStream()); PrintWriter pw1 = new PrintWriter(s1.getOutputStream());
- Ezt duplikáljuk:
Socket s2 = ss.accept(); Scanner sc2 = new Scanner(s2.getInputStream()); PrintWriter pw2 = new PrintWriter(s2.getOutputStream());
- Ezután viszont szabadon kezelhetjük a kettőt, külön, vagy akár egymásnak is átirányíhatjuk
String name1 = sc1.nextLine(); String name2 = sc2.nextLine();
Ugyanakkor kezelhetjük őket több porton is:
- ehhez csak azt kell megváltoztatni, hogy a második
ServerSocket
egy másik porton hallgatózzon:ServerSocket ss2 = new ServerSocket(54321); Socket s2 = ss2.accept(); Scanner sc2 = new Scanner(s2.getInputStream()); PrintWriter pw2 = new PrintWriter(s2.getOutputStream());
Teljes kód:
public static void main(String[] args) throws Exception {
int PORT = 12345;
try (
ServerSocket ss = new ServerSocket(PORT);
//ServerSocket ss2 = new ServerSocket(54321);
Socket s1 = ss.accept();
Scanner sc1 = new Scanner(s1.getInputStream());
PrintWriter pw1 = new PrintWriter(s1.getOutputStream());
//Socket s2 = ss2.accept();
Socket s2 = ss.accept(); //ezt kommentelni kell ha két porton szeretnénk!
Scanner sc2 = new Scanner(s2.getInputStream());
PrintWriter pw2 = new PrintWriter(s2.getOutputStream());
) {
String name1 = sc1.nextLine();
String name2 = sc2.nextLine();
while (true) {
if (!sc1.hasNextLine()) break;
sendMsg(name1, sc1, pw2);
if (!sc2.hasNextLine()) break;
sendMsg(name2, sc2, pw1);
}
}
}
Ezt oldja meg az alábbi feladat is:
A szerverhez kapcsolódjon két kliens egymás után (ugyanazon a porton) úgy, hogy a szerver mindkét kapcsolatot egyszerre tartja nyitva. A kliensek először egy-egy sorban a saját nevüket küldik át, majd felváltva írhatnak be egy-egy sornyi szöveget. A beírt üzeneteket küldje át a szerver a másik kliensnek ilyen alakban:
<másik kliens neve>: <másik kliens üzenete>
. Ha valamelyik kliens bontja a kapcsolatot, akkor a szerver zárja be a másik klienssel a kapcsolatot, és lépjen ki.
mintafájlok: gy5/Parhuzamossag.java
- létrehozunk szálat:
Thread t1 = new Thread()
- elindítjuk:
t1.start();
- megvárhatjuk, hogy befejezze a futását:
t1.join();
egyben:
Thread t1 = new Thread(() -> {
myClass.myFun1();
myClass.myFun2();
});
Thread t2 = new Thread(() -> {
myClass.myFun1();
myClass.myFun2();
});
t1.start(); // versenyhelyzet (race condition)
t2.start();
t1.join();
t2.join();
- ebben az esetben 3 szálunk volt:
t1
,t2
,main
. Ha nem írjuk ki at1.join();
t akkor amain
nem várja be annak a futánsak a végét és tovább lép. Adott esetben, ha mindez egytry(){}
blokkban történik akkor ajoin()
elhagyásával az erőforrásokat is elengedhetjük, és így például at1
szál is megszakad! Jó plda erre a gy7/MultiThreadChatServer.java amiben ha elhagynánk ajoin()
okat akkor pont ez történne! - ha valamit szeretnénk elérni mindkét szálról, úgy hogy annak az értéke bizotsan ne módosuljon amíg az egyik szál használja a másik szál által akkor szinkronizálnunk kell:
synchronized (szinkroizálandó){}
egyben:
int[] counter = { 0 };
Thread t1 = new Thread(() -> {
for (int i = 0; i < 100000; ++i) {
synchronized (counter) {
++counter[0];
}
}
});
Természetesen mindezt a kliensnél is megtehetjük, ha pl az egyik szálon írunk, másikon olvasunk.
példa: kecskés feladat : gy6/MyGoats.java
Készíts olyan chat alkalmazást, amelyben a két kliensnek nem kell egymásra várnia soronként, hanem bármikor beszélhetnek egymáshoz, és ez azonnal kiíródik a másik kliensnél.
részlet:
try (
ServerSocket ss = new ServerSocket(12345);
) {
while (true) {
ClientData client = new ClientData(ss);
synchronized (otherClients) {
otherClients.add(client);
}
new Thread(() -> {
while (client.sc.hasNextLine()) {
String line = client.sc.nextLine();
synchronized (otherClients) {
for (ClientData other : otherClients) {
other.pw.println(line);
other.pw.flush();
}
}
}
synchronized (otherClients) {
otherClients.remove(client);
try {
client.close();
} catch (Exception e) {
// won't happen
}
}
}).start();
}
}
egész kód: gy7/MultiThreadChatServerV3.java
mintafájl: gy8/RMIDeploy.java
Szeretnénk eléréni, hogy a kliens közvetlenül a serveren tudjon függvénykeet, metódusokat, eljárásokat hívni, paraméterezni. A Deployban létrehozzuk a serverünk pár plédányát:
- Lefoglaljuk a
PORT
ot, meg egyebet:Registry registry = LocateRegistry.createRegistry(PORT);
- Létrehozzuk ezen a szerverünk egy példányát:
registry.rebind("rmiAppend", new RemoteAppendTxtServer());
public static void main(String args[])
throws Exception
{
final int PORT = 12345;
Registry registry = LocateRegistry.createRegistry(PORT);
// Registry registry = LocateRegistry.getRegistry();
registry.rebind("rmiAppend", new RemoteAppendTxtServer());
}
Ezután mintha egy osztály lenne felkonfiguráljuk, létrehozunk változókat, konstruktorokat: mintafájl: gy8/RemoteAppendTxtServer.java
public class RemoteAppendTxtServer
extends java.rmi.server.UnicastRemoteObject
implements RemoteAppendTxtInterface
{
String appendTxt;
public RemoteAppendTxtServer() throws RemoteException
{
this("default");
}
public String appendTxt(String str) throws RemoteException
{
return str + appendTxt;
}
}
Ezután már csak egy interface
re van szükségünk, hogy tudjunk kapcsolódni a klienstől:
mintafájl: gy8/RemoteAppendTxtInterface.java
import java.rmi.*;
public interface RemoteAppendTxtInterface extends Remote
{
String appendTxt(String str) throws RemoteException;
// MyData appendTxt(MyData str) throws RemoteException;
}
A kliensnél létrehozzuk az interface
nek megfelelő proxy
nkat:
RemoteAppendTxtInterface rmiServer = (RemoteAppendTxtInterface)(registry.lookup(srvName));
Ahol mostantól nyugodtan hívhatjuk az interface
n megengedett eljárásokat:
String reply = rmiServer.appendTxt(text);
Lottós feladat : Lottós feladat fájljai
kitlei.web.elte.hu/segedanyagok
gy10 A táblákon csak a szokásos SQL parancsok használhatóak!
Elégségesért az alapfeladatot kell teljesen megoldani.
- Az adatok (osztály neve, port stb.) a megadott alakban szerepeljenek a programban.
- A megoldáshoz célszerű osztályokat, segédfüggvényeket, adatszerkezeteket stb. létrehozni.
- Használhatók az alábbi segédanyagok:
- A JDK dokumentációja itt érhető el.
- A gyakorlatok anyagai (és az adatbáziskezeléshez szükséges jar fájlok) itt érhetők el.
- A megoldást teljesen önállóan kell elkészíteni. Együttműködés/másolás esetén minden érintett fél elégtelent kap. A további feladatok eggyel növelik a megszerzett jegyet, és tetszőleges sorrendben adhatók hozzá a programhoz. Beadás: az elkészült megoldás fájljait
zip
-pel kell tömöríteni a feltöltéshez. IDE-ben készült megoldásnál a teljes projekt becsomagolható.
!! Az alapfeladatban se a szervernek, se a kliensnek nem kell párhuzamosan (több szálon) működnie. Készíts olyan szervert az Auction osztályba, amely a
2121
porton indul el, és egy aukciós házat szimulál. A szerver egy klienst vár, majd a kliens lecsatlakozása után csatlakozhat újabb, és újabb kliens. A kliensek szövegesen kommunikálnak a szerverrel; az első sorban elküldik a nevüket, majd a következő sorokban az alábbi három lehetőségből választhatnak.
put <item_name>
: az adott nevű tárgyat meghirdeti (tegyük fel, hogy még nincs azonos nevű tárgy), kezdetben0
áronlist
: lekérdezi a meghirdetett tárgyakat. A szerver először elküld egy számot (hány meghirdetett tárgy van), majd soronként egyet-egyet anév ár nyertes
formábanbid <item_name>
: a felhasználó licitál a tárgyra, eggyel megnövelve az értékét, és az aktuális nyertest a felhasználóra állítva Ehhez a szerverhez készíts egy klienst is azAuctionClient
programba.
Módositsd a szervert, hogy egyszerre tetszőlegesen sok klienst engedjen csatlakozni, és mind párhuzamosan használhassák az előző feladatban megvalósított parancsokat. Az aukciók legyenek limitált idejűek: a meghirdetéstől számítva 30 másodpercig tartanak. Az idő lejárta után befejeződnek: többet nem lehet rájuk licitálni, és nem jelennek meg a listában. Amikor az aukció lejár, a szerver üzenetet küld a győztes kliensnek a nyereményéről.
A szerver exportáljon egy RMI objektumot, amely a
BidHistory
interfészen keresztül, abid_history
néven érhető el. Az interfésznek legyen egy olyan metódusa, ami visszaadja az összes eddigi licit adatait (ki, mire, mennyiért) egy időben növekvő listában. Az interfész másik metódusát meghívva lehessen átváltani nyitva/zárvatartás között. Amíg az aukciós ház zárva tart, a licitálás szünetel, és a szerver egy ezt jelző üzenetet küld vissza a klienseknek.
A szerver tárolja el adatbázisban, ki hány tárgyat hirdetett meg eddig összesen. Ez az érték maradjon meg a szerver újraindításakor is, ne kezdődjön előről nulláról. Mindenki maximum három tárgyat hirdethet meg - az afölötti kéréseket a szerver figyelmen kívül hagyja.
Készíts cikkek írására egy szerver-kliens alkalmazást. Készíts egy
ujsag.Cikk
típust, ami egy cikket tartalmaz, egy címet. valamint szavak listáját. Készíts egyujsag.Server
típust. Ami egy futtatható' Java osztály. A main függvény indítson egy szervert, az első paranccsori paraméterként megadott porton. es várja egymás utáni kliensek csatlakozásat. A klienstöl csatlakozás után először egy sort várjon. ami a cikk címét tartalmazza. majd ezután szavak sorozatát A szerver nem küld válaszokat a kliensnek A szerver tárolja el a kapott cikkeket egy adatszerkezetbe. Amennyiben egy cikk korábban már létezett. azt írja felül. Keszits egyujsag.iro
nevü futtatható Java osztályt. A program kérjen be a felhasználótól a standard bemeneten egy címet. majd szavak listáját a standard bemenet zárásáig. és azokat folyamatosan küldje el a paranccsori paraméterként megkapott szerveren. (az első parancssori paraméter a host. a második a port)
Kidolgozva: Server
Készíts sportmérkőzések lebonyolítására egy szerver-kliens alkalmazást.
- Készíts egy
sport.Pont
típust, ami azt reprezentálja, ha egy csapat pontot szerzett. Tartalmazzon két adattagot: hányadik csapat (1, vagy 2) szerezte a pontot. és a játék hányadik másodpercében.- Készíts egy
sport.Merkozes
típust, ami egy mérkőzést reprezentál: tartalmaz két csapatnevet (stringek), valamint a pontok listáját.- Készíts egy
sport.Szerver
típust, ami egy futtatható Java osztály. A main függvény indítson egy szervert az első paranccsori paraméterként megadott porton, es várja egymás utáni kliensek csatlakozásat. A klienstől csatlakozás után először két sort várjon. ami a két csapat nevét tartalmazza, majd ezután pontok sorozatát. A kliens a pontoknál csak azt küldi el. melyik csapat szerezte a pontot (szám formájában), az idő automatikusan számolódik az alapján, a kliens hány rnásodperce csatlakozott. A szerver nem küld válaszokat a kliensnek. A szerver jelenítse meg a standard kimeneten az aktuális mérkőzés információit minden változás után.- Készíts egy
sport.Feljegyzo
nevű futtatható Java osztályt. A program kérjen be a felhasználótól a standard bemeneten két csapatnevet, majd sorok listáját a jatek_vege. üzenetig. A sorok vagy 1-est. vagy 2-est, vagy a latek_vege“ üzenetet tartalmazhatják.