Java och nätverk Läsanvisningar Skansholm (med Swing) kapitel 18 Budd kapitel 22 1
Dagens ämnen Introduktion till nätverksprogrammering i Java TCP/IP Portar, sockets, strömmar Exempel: multitrådad bank-server med klienter Exempel: enkel chat, multitrådad chat 2
Introduktion till nätverksprogrammering i Java Nätverksprogrammering i Java är lätt och roligt Paketet java.net innehåller allt du behöver, och gömmer allt svårt : import java.net.* TCP/IP - Transport Control Protocol / Internet Protocol är implementerat och därmed gömt i klasserna i java.net 3
Grunderna i TCP/IP IP-adresser Dataströmmar via Internet Sockets Klasserna i java.net för att kommunicera via TCP/IP Att öppna nätverksansluningar Server/client applikationer 4
TCP och IP Två olika protokoll IP Internet Protocol TCP Transport Control Protocol Definierar tillsammans hur Internet fungerar 5
IP Internet Protocol Identifierar datorer på nätet med 4 bytes (130.238.12.131) Alla datorer på nätet kan identifieras med hjälp av detta nummer Mappas till människovänliga namn (t.ex. dromedar.it.uu.se) av Domain Name Servers (DNS) Under IP sker all kommunikation i form av paket 6
TCP Transport Control Protocol Möjliggör att Internet-resurser kan användas som strömmar TCP garanterar att: Data som skickas till en viss maskin anländer till just denna maskin Data kan delas upp och skickas i flera paket som kan ta olika vägar över nätet. Sätts ihop på destinationsdatorn. 7
Portar Olika data (html, epost, etc) ska skickas till olika program...... portnummer bestämmer till vilket program data skickas. Portnummer under 1024 är reserverade för välkända tjänster som t.ex. epost (25 - smtp), ftp (21), etc. Webbsidor (http) skickas till port 80 Portnummer över 1024 kan användas av oss för egna servrar t.ex. 8
Identifiering: Sockets IP-adress + portnummer definierar tillsammans en unik tjänst på en maskin En sådan tjänst kan vara t.ex. en webbserver. Klientprogram lyssnar också på vissa portar för att få information tillbaka Socket = IP-adress + portnummer Servers kommer ihåg sina klienters sockets och kan utföra tjänster för flera klienter samtidigt" 9
Sockets och strömmar Sockets definierar ändstationerna i tvåvägskommunikation TCP garanterar att data kommer i rätt ordning Alltså: man kan läsa från /skriva till sockets som från/till strömmar TCP gömmer att data kommer från en annan maskin via Internet Javas Stream-klasser gör att data via nätet ser ut precis som data i en lokal fil 10
Servers och klienter En server lyssnar efter anslutningar på en viss port När anslutning anländer: får servern en socket som används i kommunikationen med klienten startar servern en dialog med klienten via denna socket Klienten startar uppkopplingen och kommunicerar via en socket som representerar servern 11
Server-design Serverprogram är ständigt igång Lyssnar efter begäran om anslutning Deltar i dialoger (skriver/läser via sockets) 12
Multitrådade servers Väntar på anslutning från klient Vid begäran om anslutning: Servern startar ny tråd som har hand om all kommunikation Tillbaka till vänteläget Detta möjliggör betjäning av flera klienter simultant" Fel i en klient påverkar inte andra klienter 13
Klassen InetAddress representerar en internetadress Olika sätt att skapa objekt i klassen: static InetAddress getbyname(string) static InetAddress getbyaddress(byte[]) static InetAddress getlocalhost() 14
Klassen InetAddress (forts) Några metoder: String gethostname() String gethostaddress() byte[] getaddress() 15
Test av klassen InetAddress Programmet nedan skapar adressen till mindator. public class InetTest { public static void main(string[] args) { try { InetAddress ipserver1 = InetAddress.getByName("dromedar.it.uu.se"); InetAddress ipserver2 = InetAddress.getByName("130.238.12.131"); InetAddress iplocal = InetAddress.getLocalHost(); System.out.println(ipServer1.toString()); System.out.println(ipServer2.toString()); System.out.println(ipLocal.toString()); System.out.println("getHostName="+ipLocal.getHostName()); System.out.println("getHostAddress="+ipLocal.getHostAddress()); 16
} System.out.println("getAddress="+ipLocal.getAddress()); } catch (UnknownHostException e) { System.out.println("IP address not found: "+e.getmessage()); } finally { System.out.println("We are done!"); } } 17
InetAddress (forts) Programmet skriver (om man startar det på en annan av våra datorer): svenolof@harpo$ javac InetTest.java svenolof@harpo$ java InetTest dromedar.it.uu.se/130.238.12.131 dromedar.it.uu.se/130.238.12.131 harpo/130.238.12.34 gethostname=harpo gethostaddress=130.238.12.34 getaddress=[b@4d2c3c We are done! svenolof@harpo$ 18
Klasserna URL och URLConnection Det enklaste sättet att lokalisera och hämta data över nätet är med hjälp klassen URL. URL står för Uniform Resource Locator och är helt enkelt en webb-adress: komplett med protokoll, datornamn, portnummer, katalog och filnamn. Ett exempel visar bäst hur man kan använda klasserna. Programmet nedan skapar en URL, öppnar en ström och skriver innehållet i URL:en på skärmen. 19
class URLtest { public static void main(string[] args) throws MalformedURLException, IOException { URL u = new URL("http://www.csd.uu.se/datalogi/cmtrl/oopj/vt-2003/"); System.out.println( u ); // Skriver strängen ovan BufferedReader htmlkoden = new BufferedReader(new InputStreamReader(u.openStream())); 20
URLtest (forts) String raden; while ((raden = htmlkoden.readline())!= null) System.out.println( raden); URLConnection ul = u.openconnection(); ul.connect(); } System.out.println( ul.getcontentlength() ); System.out.println( new Date(ul.getDate()) ); System.out.println( new Date(ul.getLastModified()) ); System.out.println( ul.getcontenttype() ); } 21
Programmet skriver: http://www.csd.uu.se/datalogi/cmtrl/oopj/vt-2003/ <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> <html> <head> <title>oop med Java våren 2003</title> </head> <body bgcolor="#ffffff" text="#000000" link="#0000ff" vlink="#800000" alink="#ff0000"> <blockquote> <b> <a href="http://www.uu.se/">uu</a> <a href="http://www.it.uu.se/">it</a> <a href="http://www.csd.uu.se/">csd</a> </b> <h1 align="center"><img src="http://www.csd.uu.se/pics/logos/uu_it_sv.gif"></h1> <h1 align="center">objektorienterad programmering med Java våren 2003</h1> <hr> 22
Avancerade tjänster Klassen URL beskriver endast en fil på en dator. Men som vi vet finns också många tjänster (epost, webbservrar, ftp, m.m.) som man vill kunna använda. En socket En socket är ena halvan av en tvåvägsförbindelse mellan två program som kommunicerar över ett nätverk. En socket är associerad med ett portnummer. 23
Klasserna Socket och ServerSocket Klassen Socket: avsedd för klienter används för att koppla upp sig mot någon server Klassen ServerSocket: avsedd för servers väntar på inkommande uppkopplingar 24
Klassen Socket En socket kan Koppla upp sig mot en annan dator Sända data Ta emot data Stänga uppkopplingen 25
Klassen ServerSocket Brukar bindas till en port Lyssnar efter inkommande data Väntar på uppkopplingar från andra maskiner 26
En ServerSockets liv: 1. Skapas på en viss port med konstruktorn 2. Lyssnar efter inkommande uppkopplingar med metoden accept() när en klient försöker koppla upp sig......returnerar metoden ett Socket-objekt som kopplar samman klient och server 27
En ServerSockets liv (forts): 3. Servern använder Socketens metoder: getinputstream() och getoutputstream() för att hämta strömmar som kan användas för kommunikationen 4. Server och klient interagerar enligt överenskommet protokoll 5. Servern eller klienten eller båda kopplar ned 6. Servern återgår till steg 2: väntar 28
En enkel server Programmet nedan är en enkel server som bara ligger i en oändlig loop och väntar på att bli kontaktad. När någon klient kontaktar servern skrivs klientens namn och socketens port ut. 29
import java.net.*; import java.io.*; /** * SimpleServer.java: just listens to remote connections */ public class SimpleServer { public static void main(string [] args) { try { ServerSocket serversock = new ServerSocket(Integer.parseInt(args[0])); for (int i=1; true; i++) { [ Ta emot uppkoppling ] } } catch (IOException e) { 30
} System.out.println("Server Socket Error: "+e.getmessage()); } finally { System.out.println("Finished"); } } 31
Ta emot uppkoppling: System.out.println("Waiting for client connection #" + i + "..."); Socket sock = serversock.accept(); // waits for a connection System.out.print("Connection from client: "); System.out.print(sock.getInetAddress().getHostName()+" "); System.out.println(sock.getInetAddress().getHostAddress()); System.out.print("Remote port="+sock.getport()+" "); System.out.println("Local port="+sock.getlocalport()); System.out.println("... Done"); 32
Exempel på utskrift ( servern kontaktas med netscape och lynx från hamberg och dromedar): svenolof@harpo$ javac SimpleServer.java svenolof@harpo$ java SimpleServer 6001 Server Socket Error: Address already in use Finished svenolof@harpo$ java SimpleServer 6002 Waiting for client connection #1... Connection from client: hamberg.it.uu.se 130.238.9.198 Remote port=36772 Local port=6002... Done Waiting for client connection #2... Connection from client: dromedar.it.uu.se 130.238.12.131 33
Remote port=33799 Local port=6002... Done Waiting for client connection #3... 34
En Sockets liv 1. Skapas med konstruktorn 2. Försöker koppla upp sig mot en dator 3. Efter uppkopplingen använder de två datorerna strömmar i socketen för att skicka och ta emot data. Data kan skickas och tas emot samtidigt. Hur data tolkas beror på överenskommet protokoll. 4. När dataöverföringen är klar stänger en eller båda sidorna förbindelsen. 35
En enkel klient Programmet nedan är en enkel klient som kontaktar servern ovan. public class SimpleClient { public static void main(string[] args) { try { [ Koppla upp dig ] } catch (UnknownHostException e) { System.out.println("IP address not found: " + e.getmessage()); 36
}}} } catch (IOException e) { System.out.println("Socket cannot be created: " + e.getmessage()); } finally { System.out.println("We are done!"); 37
[Koppla upp] InetAddress ipserver = InetAddress.getByName(args[0]); Socket s = new Socket(ipServer, Integer.parseInt(args[1])); System.out.println("Server:"); System.out.println(s.getInetAddress().getHostName()); System.out.println(s.getInetAddress().getHostAddress()); System.out.println("Remote port="+s.getport()); System.out.println("Local port="+s.getlocalport()); 38
Exempel: multitrådad bank-server med klienter Ett exempel med en bank och kunder: en bankserver som tillåter flera simultana klienter. En klass BankServer, som startar upp en KlientHanterare varje gång en klient ansluter sig. En klass Konto. en klass BankClient som körs på kundens dator. 39
public class BankServer { public static Konto[] konto = new Konto[4]; // extremt liten bank public static void main ( String[] args ) { konto[0] = new Konto(1, 5000 ); konto[1] = new Konto(2, 20000 ); konto[2] = new Konto(3, 10000 ); konto[3] = new Konto(4, 10000 ); int port = Integer.parseInt( args[0] ); try { ServerSocket serversock = new ServerSocket( port ); while (true) { Socket klientsock = serversock.accept(); 40
System.out.println(klientSock.getInetAddress().getHostName() + " ansluten"); new KlientHanterare( klientsock); } } catch (IOException e ) {} } 41
BankServer (forts) public static Konto trans( int nummer, int belopp) { for (int i=0;i<4;i++) if (konto[i].getnummer()==nummer) { konto[i].trans(belopp); return konto[i]; } return null; } } 42
class Konto { private int saldo; private int nummer; Konto( int nummer, int saldo ) { this.nummer = nummer; this.saldo = saldo; } void trans( int v) {saldo += v; } int getnummer() { return nummer; } int getsaldo() { return saldo; } } 43
Klienthanterare class KlientHanterare implements Runnable { public Thread aktivitet = new Thread(this); Socket sock; DataInputStream sin; DataOutputStream sout; public KlientHanterare(Socket s) throws IOException { sock = s; sin = new DataInputStream( sock.getinputstream()); sout = new DataOutputStream( sock.getoutputstream()); aktivitet.start(); } 44
Klienthanterare(forts) public void run() { while (true) { try { int nr = sin.readint(); int belopp = sin.readint(); Konto konto = BankServer.trans( nr, belopp); sout.writeboolean( (konto!= null) ); sout.writeint( konto.getsaldo() ); } catch (IOException e) { break; } } System.out.println(sock.getInetAddress().getHostName() + " nedkopplad"); 45
try { sock.close(); } catch( IOException e) {} } } 46
BankClient import java.io.*; import java.net.*; public class BankClient { public static void main( String[] args) throws IOException { String dator = args[0]; int port = Integer.parseInt( args[1] ); Socket sock = new Socket( dator, port); System.out.println("Ansluter till "+dator+", port "+port); DataInputStream sin = new DataInputStream( sock.getinputstream()); DataOutputStream sout = new DataOutputStream( sock.getoutputstream()); 47
BufferedReader indata = new BufferedReader(new InputStreamReader(System.in)); System.out.println("Kontonummer"); String s2 = indata.readline(); int nr = Integer.parseInt(s2); System.out.println("Belopp"); s2 = indata.readline(); int belopp = Integer.parseInt(s2); sout.writeint(nr); sout.writeint(belopp); boolean ok = sin.readboolean(); int saldo = sin.readint(); System.out.println("Nytt saldo: " + saldo); sock.close(); }} 48
Mer exempel Exempel: enkel chat Program SingleChat fungerar som både server och klient. Aktiekurser 49
Sammanfattning Förvånansvärt lätt att komma igång och skriva Javaprogram som kommunicerar över Internet....men även ganska enkel kommunikation uttrycks bäst med multitrådade program. Klassen URL kan användas för att plocka ner data från nätet. Servers och klienter programmeras enkelt med klasserna ServerSocket och Socket. 50