Side 1 av 5, socket og klient-tjener, V. Holmstedt, HiO 2006 Dette dokumentet er revidert den 29.8.2006, kl:12:30. Det er foretatt rettelser i begge versjoner av klassen A_Server. Socket og ServerSocket Socket og ServerSocket brukes i programmering i nettverk. Serverprogrammer er programmer som skal kunne kontaktes av andre. Clientprogrammer er programmer som skal kunne kontakte serverprogrammer. Serverprogrammer bruker både ServerSocket og Socket. Clientprogrammer bruker bare Socket. En server kalles på norsk ofte en tjener. En client kalles på norsk ofte en klient. Grunnleggende server Det er enkelt å bygge en konfigurasjon med server og client i Java. Minste konfigurasjon Den minste konfigurasjonen vises her. Den består av to deler. Den ene delen er sammensatt av to klasser som kjøres som ett program på en servermaskin. Den andre delen er klassen Client, som kjører på en klientmaskin. I denne sammenhengen kan maskin godt bety for eksempel en instans av cmd i Windows XP. Med to slike instanser kan altså både disse og de senere eksemplene testes på en og samme fysiske maskin. public class A_Server { ServerSocket servsock = new ServerSocket(22003); Socket s = servsock.accept(); new A_ClientThread(s).start(); catch (IOException e) { Denne koden registrerer seg som server og vil ha melding når klienter henvender seg til maskinen med port 22003 som argument. Metoden accept blokkerer til en klient henvender seg. En klienthenvendelse fører til at accept konstruerer en Socket som representerer klienten på servermaskinen. Klienttråden kan enkelt skrives slik: public class A_ClientThread extends Thread { Socket s; public A_ClientThread(Socket s) {
Side 2 av 5, socket og klient-tjener, V. Holmstedt, HiO 2006 this.s = s; public void run() { System.out.println("Client ble vekket av "+s); Begge disse klassene danner et program som kjøres på serveren. Her brukes socket-objektet bare til å skrive ut informasjon om den fysiske klienten. Klienter for denne serveren kan kjøre i et vilkårlig antall på mange ulike maskiner. De har det felles at de kan gjøre henvendelser over nettverket til klassen A_Server. En klient som kan gjøre dette, kan enkelt skrives slik: public class Client { Socket socket = new Socket("128.39.117.131",22003); catch (Exception e) { Testing av dette kan utføres på samme maskin, eller på to eller flere ulike maskiner. Adressen til maskinen og portnummeret som brukes må regulereres, slik at verdiene stemmer med det miljøet programmet testes i. Ved pakkeorientert utvikling i Java kan programmene startes slik: java pakke.entrypoint Ved bruk av Eclipse for Windows XP kan du finne prosjektets mappeadresse ved å klikke på Project-Properties og kopiere Location. Denne adressen kan du lime inn med høyre museklikk i cmd-instansen. Dersom du for eksempel vil starte Client som har sine.class-filer plassert i mappen bin, blir miljøet for oppstart omtrent slik: c:\>documents and Settings\brukernavn\workspace\test\bin>java pakke.client Det lar seg også gjøre å kjøre testene i Eclipse, men da bør output basere seg på grafiske komponenter, siden det er bare ett konsoll. Utveksling av data For en server er det vanligvis påkrevet at den vender tilbake til lyttetilstand etter å ha startet en klienttråd. På denne måten vil serveren kunne betjene mange klienter på en gang. Serveren kan definere en uendelig løkke for å få til dette:
Side 3 av 5, socket og klient-tjener, V. Holmstedt, HiO 2006 public class A_Server { ServerSocket servsock = new ServerSocket(22003); while (true) { Socket s = servsock.accept(); new A_ClientThread(s).start(); catch (IOException e) { Løkken lar seg avbryte med CTRL+C. Klienttråden utnytter nå socket-objektet til å skaffe seg en inputstrøm fra klienten. public class A_ClientThread extends Thread { Socket socket; public A_ClientThread(Socket s) { this.socket = s; public void run() { System.out.print("Client ble vekket av "+socket); System.out.println(" med følgende melding:"); System.out.println("["+melding()+"]"); private String melding() { String s = ""; InputStream in = socket.getinputstream(); BufferedReader br = new BufferedReader(new InputStreamReader(in)); String l = null; while ((l=br.readline())!=null) { s += l; catch (IOException e) { e.printstacktrace(); return s; Klienten kan nå sende meldinger til serveren. Den tilsvarende klienttråden på serversmaskinen gjentar meldingen. public class Client {
Side 4 av 5, socket og klient-tjener, V. Holmstedt, HiO 2006 Socket socket = new Socket("128.39.117.131",22003); OutputStream out = socket.getoutputstream(); PrintWriter pw = new PrintWriter(out); pw.print("hei på deg, hilsen en klient!"); pw.close(); catch (Exception e) { Dette eksemplet har vist at klienten kan sende data til serveren, og at serveren kan stå og vente på et uendelig antall klienthenvendelser av samme type. Vedvarende forbindelse og protokoll Klient-tjener-systemet kan også programmeres til å vedlikeholde forbindelsen til en klient basert på en protokoll. I det neste eksemplet sender serveren nye tilfeldige tall til klienten, helt til klienten sender STOP. Klassen A_Server er uendret. Klassen A_ClientThread er endret. Den sender nå tallverdier, i string-format, til klienten, og venter på svar. Hvis svaret er STOP, brukes break til å avbryte den uendelige løkken. public class A_ClientThread extends Thread { Socket socket; public A_ClientThread(Socket s) { this.socket = s; PrintWriter pw; BufferedReader br; public void run() { InputStream in = socket.getinputstream(); OutputStream out = socket.getoutputstream(); pw = new PrintWriter(out); br = new BufferedReader(new InputStreamReader(in)); while (true) { sendnumbertoclient(); if (response().equals("stop")) break; catch (Exception e) { private String response() throws Exception { String l = br.readline(); System.out.println(socket.getPort()+" svarte "+l); return l;
Side 5 av 5, socket og klient-tjener, V. Holmstedt, HiO 2006 int n = 1000; private void sendnumbertoclient() { pw.println("" + n++); pw.flush(); sleep(1000); catch (Exception e) { Klienten starter med å lytte etter tall som skal skrives ut. Deretter er det tilfeldigheter som avgjør om det skal sendes en kommando for å motta flere tall, eller kommandoen for å stoppe. public class Client { static BufferedReader br; static PrintWriter pw; Random r = new Random(); Socket socket = new Socket("128.39.117.131", 22003); OutputStream out = socket.getoutputstream(); InputStream in = socket.getinputstream(); br = new BufferedReader(new InputStreamReader(in)); pw = new PrintWriter(out); while (true) { String n = br.readline(); System.out.println("Mottok " + n); if (r.nextint(50) == 0) { sendstopp(); break; else sendmore(); catch (Exception e) { private static void sendmore() { pw.println("more"); pw.flush(); private static void sendstopp() { pw.println("stop"); pw.close();
This document was created with Win2PDF available at http://www.win2pdf.com. The unregistered version of Win2PDF is for evaluation or non-commercial use only. This page will not be added after purchasing Win2PDF.