15.3.2005 Verkko-ohjemointia TCP vs. UDP Socket, ServerSocket Datagrammit RMI 1
Javaa verkossa Sovelmat - appletit ajetaan www-selaimessa peritään jawa.awt.applet tai javax.swing.japlet (vrt. JFrame) http://java.sun.com/docs/books/tutorial/applet/ Palvelmat - servlet Java Servlet API J2EE:ssä Dynaamiset www.sivut (itse html-sivu voi olla staattinen) http://java.sun.com/docs/books/tutorial/servlets/ URL Resurssien löytäminen verkosta - Uniform resource locator Esimerkki: import java.net.*; import java.io.*; URL homepage = new URL("http://www.hut.fi/"); BufferedReader in = new BufferedReader( new InputStreamReader( homepage.openstream())); Itsenäiset ohjelmat, RMI 2
Verko-ohjelmoinnin perusta Protokollapino Ohjelmoijan ei tarvitse välittää verkkokerroksen toteutuksesta tai sitä alemmista kerroksista Esim. selainta ohjelmoitaessa (http -protokolla) ei tarvitse ohjejlmoida TCP protokollaa TCP - Transmisson Control Protocol Yhteydellinen, luotettava vrt. puhelin UDP - User Datagram Protocol Yhteydetön, tietoa voi kadota vrt. kirjekyyhkyt ylimääräinen makupala: RFC 2549 java.net - paketti tarjoaa valmiita työkaluja Sovelluskerros http, ftp, ssh,... Siirtokerrros TCP, UDP,... Verkkokerros IP,... ohjelmoijan on ensin tiedettävä tarvitseeko hän TCP vai UDP yhteyksiä 3
IP-osoite ja portinumero Yksittäinen tietokone löytyy verkosta IP:n avulla (32 bittinen) Tietokoneessa on yleensä vain yksi fyysinen verkkoliitin, jota pitkin tieto kulkee TCP/UDP:n on tiedettävä, kenelle (mille ohjelmalla) paketti pitää välittää Portit 16 -bittinen kokonaisluku - porttien 0-1023 käyttö on varattu tunnetuille ohjelmille Sovellus Portti Sovellus Portti TCP tai UDP Sovellus Portti Paketti: Portti# Data 4
Soketit (eng. Socket) URL, URLConnection ja RMI tarjoavat korkean abstraktiotason menetelmiä verkkoresurssien hyödyntämiseen http://java.sun.com/docs/books/tutorial/networking/urls/index.html RMI:stä puhutaan myöhemmin lisää Soketit ovat matalamman tason käsitteitä Asiakas - palvelin ohjelman toiminta Palvelin odottaa tiettyyn porttiin sidottua sokettia ja odottaa yhteydenottoa Palvelin hyväksyy asiakkaan yhteydenottopyynnön ja luo asiakkasta varten oman (uuden) soketin Asiakkaalle syntyy vastaa soket ja ohjelmat voivat keskustella näin luodun soket-parin avulla Serveri jatkaa toisen soketin kuuntelua uusien yhteyspyyntöjen varalta 5
Soketit (eng. socket) Soketit ovat kahden (tietoverkon avulla) keskenään keskustelevan ohjelman yhteyksien päätepisteitä Soketti on sidottu porttinumeroon Edellisellä kalvolla selitetty asiakas - palvelin ohjelmisto: http://java.sun.com/docs/books/tutorial/networking/sockets/definition.html 6
java.net.socket Asiakasohjelma luo socketin, jonka kautta se avaa virtoja ja joiden avulla asiakas voi kommunikoida palvelimen kanssa Yhteydenotto import java.net.*;... Socket s = new Socket(<palvelin>, <portti>); out = new PrintWriter(s.getOutputStream(), true); in = new BufferedReader(new InputStreamReader( s.getinputstream())); Socketin konstruktori tarvitsee koneen nimen ja portin numeron Varatut resurssit pitää lopuksimyös vapauttaa out.close(); in.close(); s.close(); 7
Palvelimen toiminta java.net.serversocket Kuunnellaan ServerSocket oliota (porttia), jonne asiakas saattaa ottaa yhteyden Odottaminen accept-metodissa Kun asiakas ottaa yhteyden accept palauttaa tavallisen Socketolion, joka kuvaa avattua yhteyttä. import java.net.*;... ServerSocket server = new ServerSocket(<portti>); //Poikkeukset Socket asiakas = server.accept();...... asiakat.getoutputstream() //asiakkaalle välitettävä tieto... asiakat.getinputstream() //asiakkaan kertoma tieto 8
Asiakas - palvelin toiminta Asiakas: Luodaan Socket-olio palvelimen nimi portti, johon otetaan yhteys Avaraan input- ja output-steam socketiin Käytetään virtoja halutun sovellusprotokollan mukaisesti Suljetaan virrat Suljetaan soketti Palvelin: Luodaan ServerSocket-olio portti, johon otetaan yhteys Odotetaan asiakasta Yhteyden synnyttyä saamme Socketolion Avaraan input- ja output-steam socketiin Käytetään virtoja halutun sovellusprotokollan mukaisesti Suljetaan virrat Suljetaan soketti 9
Usean asiakkaan palveliminen java.net.serversocket Odotetaan silmukassa josko joku ottaisi yhteyden... while (true) { Socket s = serversocket.accept()... Uuden yhteyden syntyessä saamme yhteyttä kuvaavan Socket-olion Luodaan uusi säie, joka kommunikoi asiakkaan kanssa... new AsiakasThread(s,...).start(); Nykyinen säi jää odottamaan uusia yhteyksiä 10
Datagrammit Mikäli ohjelmassa ei tarvita luotettavaa yhteyttä käytetään UDP protokollaa Datagrammi on itsenäinen tietopaketti, joka voidaan lähettää verkon kautta koneelta toiselle, mutta jonka saapumista tai saapumisjärjestystä ei taata java.net.datagramsocket, java.net.datagrampacket, java.net.multicastsocket 11
Käytetään samaa porttia kaikkien asiakkaiden kanssa tapahtuvaan kommunikointiin Yleensä monisäieohjelma, jolloin säikeen(säikeiden) on vastaanottaa yhteydenotto pyyntöjä ja lähettää vastauksia UDP-palvelin // Kyselyn vastaanotto: DatagramSocket socket = new DatagramSocket(<portti>); byte[] buf = new byte[256]; DatagramPacket p = new DatagramPacket(buf, buf.length); socket.recieve(p);... // Vastaus: InetAddress address = p.getaddress(); int port = p.getport(); // sijoitetaan puskuriin (buf) haluttu vastaus... packet = new DatagramPacket(buf, buf.length, address, port); socket.send(packet);... socket.close(); // palvelin suljetaan 12
UDP asiakas // Kyselyn lähettäminen: DatagramSocket socket = new DatagramSocket(); byte[] buf = new byte[256]; // sijoitetaan puskuriin (buf) haluttu kysely... p = new DatagramPacket(buf, buf.length, <osoite>, <portti>); socket.send(packet); Asiakas voi käyttää argumentitonta konstruktoria, sillä UDP paketin mukana kulkee tieto, porttinumerosta Järjestelmä valitsee jonkin vapaan portin palvelin voi vastata juuri siihen porttiin, josta pyyntö satuttiin lähettämään. Palvelimen vastaus käsitellään seuraavasti: packet = new DatagramPacket(buf, buf.length); socket.receive(packet); //esim: String str = new String(packet.getData()) 13
Asiakas-palvelin arkkitehtuureja Thin client (Server push / Client pull) ChatClient ChatServer ChatClient Chat ohjelmiston rakenne: ChatClient ChatClient- AndServer ChatClient- AndServer Fat client ChatClient- AndServer ChatMaster- Server 14
Sockettien avulla voitiin lähettää tietoa paketteiksi pätkittynä (ja paketeista kasattuna) tavuvirtana RMI mahdollistaa etäoliot ja toisella koneella olevien olioiden metodien kutsumisen (Remote Method Invocation) java.rmi java.rmi.server ««interface»» Remote RemoteObject RMI Naming RMISecurity- Manager RemoteServer UnicastRemote- Object java.lang MarshalledObject SecurityManager Serializable 15
RMI - arkkitehtuuri Server Skeleton rekisteri Client Stub Remote Reference Layer Transport Layer Application layer Proxy layer Lähde: Niskanen ym. 2001, s. 517 (muokaten) 16
Etäluokan rajapinta ja etäluokka import java.rmi.*; public interface Count extends Remote { public long add(long a, long b) throws RemoteException; public long sub(long a, long b) throws RemoteException; import java.rmi.*; import java.rmi.server.*; public class CountImplementation extends UnicastRemoteObject implements Count { public CountImplementation() throws RemoteException { super(); public long add(long a, long b) throws RemoteException { return a + b; public long sub(long a, long b) throws RemoteException { return a b; 17
Tynkä- ja luurankoluokat Ei tarvitse itse ohjelmoida Ovat kuitenkin sovelluskohtaisia rmic kääntäjä (Java 1.4 ja vanhemmat) javac CountImplementation.java rmic CountImplementation CountImplementation_stub.class CountImplementation_skel.class 18
Palvelimen toteutus import java.rmi.*; import java.rmi.server.*; public class CountServer { public CountServer() { System.setSecurityManager(new RMISecurityManager()); try { Count c = new CountImplementation(); //protokolla://palvelinkoneenosoite:portti/palvelunnimi Naming.rebind("rmi://localhost:1099/CountService", c); catch(exception e) { System.out.println("CountServer: poikkeus, " + e); public static void main(string args[]) { new CountServer(); Lähde: hieman muuttaen Niskanen ym. 2001, s. 531 19
Asiakkaan toteutus import java.rmi.*; public class CountClient { public static void main(string args[]) { try { Count c = (Count) Naming. lookup("rmi://localhost:1099/countservice"); System.out.println("Tulos:"); System.out.println(c.sub(10, 5)); System.out.println(c.add(2, 3)); catch(exception e) { System.out.println("CountClient: poikkeus, " + e); Lähde: supistaen ja muuttaen Niskanen ym. 2001, s. 532-523 20
Asiakas Hae etäolion edustaja palvelimen rmi-rekisterin kautta Älä käytä suoraan etäolion toteuttavan luokan nimeä, vaan toimi etärajapinnan kautta RMI lyhyesti Metodikutsut etäolioille Palvelin argumentit sarjallistuvia tai etäolioita argumentit välitetään arvoparametreinä ei viiteparametreinä rekisteröi tarjottavat etäöliot rmi-rekisteriin Etäoliot ja -rajapinnat Rajapinnat perivät Remote-rajapinnan Etäoliot toteuttavat rajapinnan ja perivät UnicastRemoteObjectin 21
Taustaa - Olioviittaukset Suoraan Olio1 Olio2 Taulun avulla Olio1 Olio2 Suorat viittaukset eivät suoraan toimi hajautetuissa järjestelmissä - eri muistiavaruus 22
Palvelinohjelma Asiakasohjelma RMI - Arkkitehtuuria toteutus Palvelin etäolio RMI rajapinta rajapinta Asiakas proxy, stub Olio http://java.sun.com/developer/onlinetraining/rmi/rmi.html 23
Proxy suunnittelumallista http://www.dofactory.com/patterns/patternproxy.aspx#um 24
Järjestelmän käynnistäminen Ongelma: miten muodosta viittaus etäkoneella olevaan olioon (yhtään proxy -oliota ei vielä ole) Ratkaisu: ulkopuolinen menetelmä Rekisteri Palvelimet rekisteröivät olioviitteitä Asiakkaat pyytävät olioviitteitä Palvelimella ja jokaisella rekisteröidyllä oliolla on nimi Asiakas antaa etäkoneen ja etäolion nimen Rekiste palauttaa tarvittavat tiedot yhteyden muodostamiseksi 25