Hálózati alkalmazások A Java egyik fő erőssége Célok Kliens-szerver architektúra Elosztott rendszer Lehetőségek Appletek Szervletek TCP/IP vagy UDP RMI, CORBA © Kozsik Tamás 2000-2006
Internet hálózatok Számítógépek azonosítása: IP cím 32 bites szám, pl. 157.181.42.42 Neveket rendelünk a gépekhez: DNS Szerver programok azonosítása IP cím mellett egy portszám is, 0-65535 0-1023: rendszergazda jog kell hozzájuk 1-255: általánosan elterjedt szolgáltatások HTTP - 80, TELNET - 23, SSH - 22, stb. © Kozsik Tamás 2000-2006
IP, TCP, UDP IP: csomagkapcsolt - az alap UDP: szintén csomagkapcsolt (mint egy levél) Az IP jellemzőit örökli (pl. csomagméret korlátozás) A csomagok érkezési sorrendje nem definiált Csomagok el is veszhetnek Nincs visszaigazolás a fogadótól Hatékony TCP: kapcsolat-elvű (mint egy telefonbeszélgetés) Garantálja, hogy minden elküldött információ a küldés sorrendjében megérkezik Sok erőforrás (IP csomagok visszaigazolása, stb.) © Kozsik Tamás 2000-2006
Kliens-szerver architektúra Asszimetrikus kapcsolatfelvétel Szerver: passzív egy gép egy portján várja a kliensek kapcsolatfelvételi igényét Kliens: aktív ismeri a szerver helyét, kezdeményezi a kapcsolatot Kommunikáció: már szimmetrikus Mindketten küldhetnek információt a másiknak Egy szerverhez több kliens egy időben © Kozsik Tamás 2000-2006
Socket A BSD UNIX világból származik A kommunikációs csatorna végpontjai java.net.Socket írni lehet rá, ami elmegy a másik gépre a másik folyamatnak olvasni lehet róla, amit a másik gépen a másik folyamat ír © Kozsik Tamás 2000-2006
Számítógép Output Stream Input Stream Program Socket Input Stream © Kozsik Tamás 2000-2006
TCP kapcsolat kiépítése Szerver: java.net.ServerSocket létrehozása adott porton kliens várása a létrejött kapcsolatot egy Socket reprezentálja Kliens egy Socket létrehozása: adott számítógép adott portján figyelő szerverprogramra való rácsatlakozás © Kozsik Tamás 2000-2006
Java-ul Szerver Kliens ServerSocket ss = new ServerSocket(1234); Socket s = ss.accept(); Kliens Socket s = new Socket("www.elte.hu",80); © Kozsik Tamás 2000-2006
Kommunikáció a kapcsolat felépítése után Mind a kliensen, mind a szerveren lekérjük a bemeneti és kimeneti csatornákat A kliens Socket-jának kimenetije rá van csatlakoztatva a szerver Socket-jának bemenetijére és fordítva... Ezeken keresztül lehet kommunikálni InputStream is = s.getInputStream(); OutputStream os = s.getOuputStream(); © Kozsik Tamás 2000-2006
import java.net.*; import java.io.*; public class Böngésző { public static void main(String[] args) throws IOException { Socket s = new Socket("www.elte.hu", 80); InputStream is = s.getInputStream(); OutputStream os = s.getOutputStream(); PrintWriter out = new PrintWriter( new OutputStreamWriter(os) ); BufferedReader in = new BufferedReader( new InputStreamReader(is) ); out.println("GET /index.html HTTP/1.0"); out.println(); out.flush(); String line; while ((line = in.readLine()) != null) System.out.println(line); in.close(); out.close(); s.close(); } © Kozsik Tamás 2000-2006
import java.net.*; import java.io.*; public class Ismétlő { public static void main(String[] args) throws IOException { ServerSocket ss = new ServerSocket(1234); Socket s = ss.accept(); InputStream is = s.getInputStream(); OutputStream os = s.getOutputStream(); PrintWriter out = new PrintWriter( new OutputStreamWriter(os) ); BufferedReader in = new BufferedReader( new InputStreamReader(is) ); String line; while ((line = in.readLine()) != null){ out.println(line); out.flush(); } in.close(); out.close(); s.close(); © Kozsik Tamás 2000-2006
Feladat Írj chat programot. Paraméter nélkül elindítva szerverként viselkedjen. A kliens elindításához parancssori argumentumban kell megadni a szerver IP címét. Ha nem AWT-s programot írsz, hanem alfanumerikusat, akkor két végrehajtási szálat kell írnod! Írd meg úgy, hogy egyszerre több kliens is lehessen összekapcsolódva! Ehhez többszálú programot kell írnod! © Kozsik Tamás 2000-2006
HTTP Hypertext Transfer Protocol TCP/IP feletti réteg Kérés-válasz protokoll Szöveges HTTP/1.0 vagy HTTP/1.1 kérés/válasz, fejlécek, üres sor, törzs fejléc: kulcs: érték(ek) HTTP/1.0 esetén nem kötelező fejlécmezőt küldeni, HTTP/1.1 esetén „Host” kötelező © Kozsik Tamás 2000-2006
HTTP kérés HTTP/1.0 HTTP/1.1 GET, POST, HEAD PUT, DELETE, OPTIONS, TRACE, CONNECT © Kozsik Tamás 2000-2006
HTTP válasz 1xx: Informational - a kérés feldolgozás alatt 2xx: Success - sikeres végrehajtás 3xx: Redirection - a válasz előállításához további tevékenységek szükségesek 4xx: Client Error - hibás, illetve teljesíthetetlen kérés 404: Not found 5xx: Server Error - a szerver saját hibájából nem képes a helyes kérés megválaszolására © Kozsik Tamás 2000-2006
HTTP fejlécek User-agent: Mozilla/3.0Gold Server: Apache/1.2b3-dev Last-Modified: Fri, 31 Dec 1999 23:59:59 GMT Content-Type: image/gif Content-Length: 1527 Date: Fri, 31 Dec 1999 23:59:59 GMT © Kozsik Tamás 2000-2006
HTTP/1.1 kliens Kell a Host fejléc Chunked Transfer-Encoding Host: www.elte.hu:80 Egy IP címhez több HTTP szerver tartozhat Chunked Transfer-Encoding Perzisztens TCP kapcsolat 100 Continue © Kozsik Tamás 2000-2006
Chunked Transfer-Encoding HTTP/1.1 200 OK Date: Fri, 31 Dec 1999 23:59:59 GMT Content-Type: text/plain Transfer-Encoding: chunked 1a; ignore-stuff-here abcdefghijklmnopqrstuvwxyz 10 1234567890abcdef some-footer: some-value another-footer: another-value [blank line here] © Kozsik Tamás 2000-2006
Perzisztens TCP kapcsolat Egy megnyitott kapcsolaton több kérés/válasz Connection: close fejléc, ha nem akarunk perzisztens kapcsolatot A szerver is küldhet ilyen választ, és utána zárja is a kapcsolatot © Kozsik Tamás 2000-2006
100 Continue Jelzi, hogy a szerver nemsokára küldi az igazi választ Feldolgozás: általában figyelmen kívül hagyjuk HTTP/1.1 100 Continue HTTP/1.1 200 OK Date: Fri, 31 Dec 1999 23:59:59 GMT Content-Type: text/plain Content-Length: 42 ... © Kozsik Tamás 2000-2006
HTTP/1.1 szerver Host fejléc megkövetelése Abszolút URL a kérésben (proxy) Chunked data a kérésben Perzisztens kapcsolat, Connection fejléc Continue üzenetek küldése Date header (caching) Date: Fri, 31 Dec 1999 23:59:59 GMT If-Modified-Since: és If-Unmodified-Since: fejlécek a kérésben Válaszolni legalább a GET és HEAD kérésekre Elfogadni HTTP/1.0-s kéréseket © Kozsik Tamás 2000-2006
Formok feldolgozása, CGI POST: a kérés törzsében mennek a form adatai egy CGI program a szabványos bemenetről olvashatja be GET: a kérés URL-ben vannak elkódolva a form adatai egy CGI program a QUERY_STRING környezeti változóban kapja meg GET /path/script.cgi?field1=value1&field2=value2 HTTP/1.0 URL encoding (=, &, %, +, non-printable ch) name=Lucy&neighbors=Fred+%26+Ethel © Kozsik Tamás 2000-2006
SMTP TCP/IP feletti réteg Szöveges protokoll SMTP szerver általában a 25-ös porton telnettel könnyen kipróbálható © Kozsik Tamás 2000-2006
gipsz@picasso:~$ telnet localhost 25 Trying 127.0.0.1... Connected to picasso (127.0.0.1). Escape character is '^]'. 220 localhost.localdomain ESMTP Sendmail 8.11.2/8.11.2; Mon, 8 Mar 2004 18:02:52 +0100 ehlo picasso.elte.hu 250-localhost.localdomain Hello picasso [127.0.0.1], pleased to meet you 250-ENHANCEDSTATUSCODES 250-8BITMIME 250-SIZE 250-DSN 250-ONEX 250-ETRN 250-XUSR 250 HELP mail from: gipsz@picasso.elte.hu © Kozsik Tamás 2000-2006
mail from: gipsz@picasso.elte.hu 250 HELP mail from: gipsz@picasso.elte.hu 250 2.1.0 gipsz@picasso.elte.hu... Sender ok rcpt to: kovacs@miro.elte.hu 250 2.1.5 kovacs@miro.elte.hu... Recipient ok data 354 Enter mail, end with "." on a line by itself To: Kovacs Istvan <kovacs@miro.elte.hu> From: Gipsz Jakab <gipsz@picasso.elte.hu> Subject: Ez nem spam!!! Szia haver! Na mi ujsag? gipsz . 250 2.0.0 i28H5G013354 Message accepted for delivery © Kozsik Tamás 2000-2006
250 2.0.0 i28H5G013354 Message accepted for delivery quit 221 2.0.0 localhost.localdomain closing connection Connection closed by foreign host. gipsz@picasso:~$ © Kozsik Tamás 2000-2006
Datagram Az UDP protokoll megvalósítása: DatagramSocket és DatagramPacket Példa: kliens küld szervernek, szerver visszaküldi dátummal Multicast lehetőség © Kozsik Tamás 2000-2006
DatagramSocket socket = new DatagramSocket(); byte[] buf; buf = args[1].getBytes(); InetAddress address = InetAddress.getByName(args[0]); DatagramPacket packet = new DatagramPacket(buf, buf.length, address, 4445); socket.send(packet); buf = new byte[256]; packet = new DatagramPacket(buf, buf.length); socket.receive(packet); System.out.println(new String(packet.getData())); socket.close(); © Kozsik Tamás 2000-2006
DatagramSocket socket = new DatagramSocket(); byte[] buf; buf = new byte[100]; DatagramPacket packet = new DatagramPacket(buf, buf.length); socket.receive(packet); buf = (new String(packet.getData()) + new Date().toString()).getBytes(); InetAddress address = packet.getAddress(); int port = packet.getPort(); packet = new DatagramPacket(buf, buf.length, address, port); socket.send(packet); socket.close(); © Kozsik Tamás 2000-2006
Elosztott rendszerek A program különböző komponensei különböző gépeken futnak. Ebbe belefér a kliens/szerver architektúra is A komponensek kommunikációja: objektumok egymás metódusait hívják A kommunikációs részleteket elrejtik a programozó elől Megvalósítás Remote Method Invocation (Java-Java) CORBA (Java-*) © Kozsik Tamás 2000-2006