Første
Java i netværk serie, Planche nr. 35
Kursus Indhold

Udskrift af : Java i netværk

Planche 1 : Java i netværk

Java er netværksorienteret

Planche 2 : Applet

Applets implementerer en række netværkforbindelser

Hvilke muligheder findes

Planche 3 : APPLET-tag

(fra Java Intro)
Appearance: <APPLET CODE=string HEIGHT=n WIDTH=n> </APPLET>
Attributes: CODEBASE=URL, CODE=string, NAME=string, ALT=string, ALIGN=left|right|top|middle|bottom, HEIGHT=n, WIDTH=n, HSPACE=n, VSPACE=n
Bemærk CODEBASE parameter!

CODEBASE er en URL, der kan være forskellig fra den URL, hvor HTML-siden (med APPLET-tag) hentes fra.

Planche 4 : Billeder

gif-filer og jepg-filer kan læses direkte via URL fra en applet.

Applet klassen har to getImage() metoder:

OBS! Only applets can use the Applet getImage() methods. Moreover, the Applet getImage() methods don't work until the applet has a full context (AppletContext). For this reason, these methods do not work if called in a constructor or in a statement that declares an instance variable. You should instead call getImage() from a method such as init().

Planche 5 : Billeder - toolkit

Hvis man ønsker at anvende getImage() uden for en appletklasse, kan man forsøge sig med en Toolkit-klasse:

OBS! You can get a Toolkit object either by invoking Toolkit's getDefaultToolkit() class method or by invoking the Component getToolkit() instance method. The Component getToolkit() method returns the toolkit that was used (or will be used) to implement the Component.

Planche 6 : Netværk til husbehov

Planche 7 : Netværk i Java

Javaprogrammer har adgang til nettet via java.net-pakken.

Planche 8 : URL

Planche 9 : URL-adresse

Uniform Resource Language

    PROTOKOL://HOSTNAME:PORTNR/FILNAVN#REFERENCE
Hvor
PROTOKOL Protokolbetegnelse: http, ftp, file ...
HOSTNAME Internet navn eller IP-adresse på maskinen, hvor resourcen findes.
FILNAVN Filnavn og -sti (Kan indeholde /).
PORTNR Portnummer (udelades ofte).
REFERENCE En reference inden for en fil (e.l).

Planche 10 : Opret URL-objekt

Hvis man har en komplet URL, kan man oprette et URL-objekt med:
	URL urlobj = new URL("http://www.blanet.dk/");

URL-konstruktør

	URL (String fuldURL);
Man kan oprette en relativ URL med et andet URL-objekt
	URL relobj = new URL(urlobj, "index.html");

Generel URL-konstruktør

	URL (URL baseobj, String relnavn);
Andre konstruktører:
	URL (String protokol, String hostnavn, String filnavn);

	URL (String protokol, String hostnavn, int portnr, String filnavn); 

Planche 11 : URL kan give undtagelse

URL kan oprette en undtaglse: MalformedURLException.

Beskyt koden med try og catch:

try {
    URL myURL = new URL(. . .)
} catch (MalformedURLException e) {
    . . .
    // Kode til undtagelseshåndtering
    . . .
}

Planche 12 : Metoder på URL-objekt

URL-objektet kan fortolke URL'en.

import java.net.*;
import java.io.*;

public class ParseURL {
    public static void main(String[] args) throws Exception {
        URL aURL = new URL("http://www.blanet.dk:80/kursus/java/links.html#udpak");
        System.out.println("protocol = " + aURL.getProtocol());
        System.out.println("host = " + aURL.getHost());
        System.out.println("filename = " + aURL.getFile());
        System.out.println("port = " + aURL.getPort());
        System.out.println("ref = " + aURL.getRef());
    }
}

Planche 13 : Læs fil fra server (Øvelse 6)

URL kan bruges direkte til at læse tekst fra en server:

public class URLlaeser {
    public static void main(String[] args) throws Exception {
        URL blanet = new URL("http://www.blanet.dk/");
        BufferedReader in = new BufferedReader(
                                new InputStreamReader(
                                blanet.openStream()));

        String inputLine;

        while ((inputLine = in.readLine()) != null)
            System.out.println(inputLine);

        in.close();
    }
}
Tilføj passende import-statements og kør koden.

Planche 14 : Proxy

Hvis man sidder på et intranet, kan det være man skal forbinde sig via en proxy. Se i browser-opsætning om det er nødvendigt.

Hvis proxyadressen er 192.66.116.254 og proxyport 8080, så kan man køre via proxy:

java -Dhttp.proxyHost=192.66.116.254 -Dhttp.proxyPort=8080 URLlaeser

Planche 15 : Åben URL-forbindelse

Når et URL-objekt er oprettet, kan det bruges til at oprette en forbindelse med.

try {
    URL blanet = new URL("http://www.blanet.dk/");
    URLConnection uc = blanet.openConnection();
} catch (MalformedURLException e) {     // new URL() failed
    . . .
} catch (IOException e) {               // openConnection() failed
    . . .
}
Metoden returnere et objekt at typen URLconnection - et forbindelsesobjekt

Husk at fange undtagelserne...

Planche 16 : Læs og skriv til URL

Man kan læse fra URL-forbindelser
import java.net.*;
import java.io.*;

public class URLConnectionReader {
    public static void main(String[] args) throws Exception {
        URL blanet = new URL("http://www.blanet.dk/");
        URLConnection bc = blanet.openConnection();
        BufferedReader in = new BufferedReader(
                                new InputStreamReader(
                                bc.getInputStream()));
        String inputLine;

        while ((inputLine = in.readLine()) != null) 
            System.out.println(inputLine);
        in.close();
    }
}
Fremhævelse viser forskel fra direkte læsning fra URL.

Planche 17 : Skrive til URL (Opgave 7)

Man kan skrive til URL-forbindelser

HVIS URL'en kan modtage

import java.io.*;
import java.net.*;

public class Reverse {
    public static void main(String[] args) throws Exception {

        if (args.length != 1) {
            System.err.println("Usage:  java Reverse string_to_reverse");
            System.exit(1);
        }

        String stringToReverse = URLEncoder.encode(args[0]);

        URL url = new URL("http://192.168.100.250/examples/servlet/Baglaens");
        URLConnection connection = url.openConnection();
        connection.setDoOutput(true);

        PrintWriter out = new PrintWriter(connection.getOutputStream());
        out.println("string=" + stringToReverse);
        out.close();

        BufferedReader in = new BufferedReader(
                                new InputStreamReader(
                                connection.getInputStream()));
        String inputLine;

        while ((inputLine = in.readLine()) != null)
            System.out.println(inputLine);

        in.close();
    }
}
Prøv dette eksempel!

(Ret evt. URL til og husk hvis proxy...)

java -Dhttp.proxyHost=192.66.116.254 -Dhttp.proxyPort=8080 Reverse "Bagvendt?"

Planche 18 : Sockets!

Planche 19 : Socket-definition

Socket: Et endpunkt i en tovejsforbindelse mellem to programmer - måske - over et netværk.

Endepunktet er bundet til et portnummer i en TCP-forbindelse.

Forbindelsen er platformsuafhængig.

Planche 20 : Java sockets

JDK pakken java.net indeholder to klasser:

Planche 21 : Socket IO

Her er et eksempel, der bruger socket-io:
import java.io.*;
import java.net.*;

public class EchoClient {
    public static void main(String[] args) throws IOException {

        Socket echoSocket = null;
        PrintWriter out = null;
        BufferedReader in = null;

        try {
            echoSocket = new Socket("taranis", 7);
            out = new PrintWriter(echoSocket.getOutputStream(), true);
            in = new BufferedReader(new InputStreamReader(echoSocket.getInputStream()));
        } catch (UnknownHostException e) {
            System.err.println("Don't know about host: taranis.");
            System.exit(1);
        } catch (IOException e) {
            System.err.println("Couldn't get I/O for the connection to: taranis.");
            System.exit(1);
        }

        BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
        String userInput;

        while ((userInput = stdIn.readLine()) != null) {
            out.println(userInput);
            System.out.println("echo: " + in.readLine());
        }

        out.close();
        in.close();
        stdIn.close();
        echoSocket.close();
    }
}
Det gennemgås efterfølgende.

Bemærk - servicen ECHO (port 7) er nu efterhånden lukket på grund af hensyn til sikkerhed på internettet.

Planche 22 : Gennemgang - 1

Linierne:
echoSocket = new Socket("taranis", 7); // (1)
out = new PrintWriter(echoSocket.getOutputStream(), true); // (2)
in = new BufferedReader(new InputStreamReader(
                             echoSocket.getInputStream())); // (3)
(1) Åbner en socket-forbindelse til port 7 på maskinen "taranis".

(2) Tager uddata-delen fra socket-forbindelsen og lader den læse fra PrintWriter.

(3) Tager inddata-delen og forbinder den til programmets inddatastrøm

(2) er data TIL serveren, (3) data FRA serveren...

Planche 23 : Gennemgang - 2

Linierne:
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
String userInput;

while ((userInput = stdIn.readLine()) != null) {
    out.println(userInput);
    System.out.println("echo: " + in.readLine());
}
Denne while-struktur læser fra konsol (stdIn) indtil brugeren trykker end-of-input-tegn (CTRL/C). Samtidig læser sidste linie fra socket-forbindelsen og skriver ekko-linien ud.

Planche 24 : Gennemgang - 3

Linierne:
out.close();
in.close();
stdIn.close();
echoSocket.close();
Lukker forbindelserne ned på en pæn måde.

Planche 25 : Socket OI - resume

  1. Åben en socket-forbindelse.
  2. Åben en inputstrøm og en outputstrøm til forbindelsen.
  3. Læs og skriv fra strømmen, sådan som "serveren" ønsker det
  4. Luk de to strømme.
  5. Luk socket-forbindelsen.
Kun punkt 3 er forskellige i forskellige anvendelser.

Planche 26 : Server

Velkommen til Client/Server teknologien!

Planche 27 : En Server (1)

En server skal lytte på en bestemt port:
try {
    serverSocket = new ServerSocket(4444);
} catch (IOException e) {
    System.out.println("Could not listen on port: 4444");
    System.exit(-1);
}
I dette tilfælde er det port 4444

Planche 28 : En Server (2)

Hvis porten er ledig:
Socket clientSocket = null;
try {
    clientSocket = serverSocket.accept();
} catch (IOException e) {
    System.out.println("Accept failed: 4444");
    System.exit(-1);
}
accept-metoden returnerer et Socket-objekt, når en klient forbinder sig...

Planche 29 : En Server (3)

Input- og outputstrømme etableres:
PrintWriter out = new PrintWriter(
                      clientSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
                        new  InputStreamReader(
                        clientSocket.getInputStream())),
String inputLine, outputLine;

while ((inputLine = in.readLine()) != null) {   
    //
    // Gør noget fornuftigt - her kopieres bare
    //
    outputLine = inputLine;
    out.println(outputLine);
    if outputLine.equals("Bye."))
        break;
}

Planche 30 : En server (4)

Oprydning:
out.close();
in.close();
clientSocket.close();
serverSocket.close();

Planche 31 : Vores tur! (Opgave 8)

En client server-opgave... Implementer ECHO-service:

Planche 32 : Flertrådede servere

EchoServer som gennemgået kan ikke håndtere flere requests samtidig. Ved at give en request til en særlig servertråd, kan man håndtere flere: Flyt den del af koden, som etablerer forbindelse og svarer en klient over en trådklasses run()-metode
public class MultiServerTraad extends Thread {
    private Socket socket = null;

    public MultiServerTraad(Socket socket) {
        super("MultiServerTraad");
        this.socket = socket;
    }

    public void run() {
	/*
	 * Åben PrintWriter out stream på ved hjælp af socket-variabel
         * Resten som i EchoServer - inklusive close() på in, out og
         * socket. Husk at håndtere evt. IOException
         */
    }
}

Planche 33 : Kontrol-klassen

Den faste del
public class MultiServer {
    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = null;
        boolean listening = true;
        ...
        serverSocket = new ServerSocket(4444);

        while (listening) {
	    Socket sok = serverSocket.accept();
	    MultiServerTraad traad = new MultiServerTraad(sok);
	    traad.start();
        }
        serverSocket.close();
    }
}
Eksemplet er forenklet (der mangler try-catch)

Planche 34 : Opgave 8b

Ovennævnte tilfælde kan faktisk implementeres i en klasse definition.

(Hint: klassen MultiServer realiseres ikke nogen steder...)

1) Lav en klasse MultiServers, der kan håndtere flere requests.

2) Få serveren til at lukke ned via en request...

Planche 35 : WoW!


© 2000 BLA*net - Leif E. Andersen, leander@blanet.dk
Første
Java i netværk serie, Planche nr. 35