16.2. At lytte på en port

For at lave et program, der fungerer som vært (dvs. som andre maskiner/programmer kan forbinde sig til), opretter man et ServerSocket-objekt, der accepterer anmodninger på en bestemt port:


      ServerSocket værtssokkel = new ServerSocket(8001);

Nu lytter vi på port 8001. Så er det bare at vente på, at der kommer en anmodning:


      Socket forbindelse = værtssokkel.accept();

Kaldet af accept() venter på, at en klient forbinder sig, og når det sker, returnerer kaldet med en forbindelse til klienten i et Socket-objekt.

Nu kan vi arbejde med forbindelsen ligesom før. Ligesom når to mennesker snakker sammen, har det ikke den store betydning, hvem der startede samtalen, når den først er kommet i gang.

I tilfældet med HTTP-protokollen er det defineret, at klienten skal først skal spørge og værten derefter svare, så vi læser først en anmodning


      String anmodning = ind.readLine();
      System.out.println("Anmodning: "+anmodning);

... og sender derefter et svar, tømmer databufferen og lukker forbindelsen (afslutter samtalen):


      ud.println("HTTP/0.9 200 OK");
      ud.println();
      ud.println("<html><head><title>Svar</title></head>");
      ud.println("<body><h1>Kære bruger</h1>");
      ud.println("Du har spurgt om "+anmodning+", men der er intet her.");
      ud.println("</body></html>");
      ud.flush();
      forbindelse.close();

Bemærk, at ud.flush() skal ske, før vi lukker soklen, ellers går svaret helt eller delvist tabt; forbindelse-objektet ved ikke, at ud-objektet har nogle data liggende, der ikke er blevet sendt endnu.

Herunder ses det fulde program:


import java.io.*;
import java.net.*;
public class Hjemmesidevaert
{
  public static void main(String arg[])
  {
    try {
      ServerSocket værtssokkel = new ServerSocket(8001);
      while (true)
      {
        Socket forb = værtssokkel.accept();
        PrintWriter ud = new PrintWriter(forb.getOutputStream());

        BufferedReader ind = 
          new BufferedReader(new InputStreamReader(forb.getInputStream()));

        String anmodning = ind.readLine();
        System.out.println("Anmodning: "+anmodning);

        ud.println("HTTP/0.9 200 OK");
        ud.println();
        ud.println("<html><head><title>Svar</title></head>");
        ud.println("<body><h1>Kære bruger</h1>");
        ud.println("Du har spurgt om "+anmodning+", men der er intet her.");
        ud.println("</body></html>");
        ud.flush();
        forb.close();
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

Resultatet bliver:


Anmodning: GET / HTTP/0.9
Anmodning: GET / HTTP/1.1
Anmodning: GET /xxx.html HTTP/1.1

Du kan afprøve programmet ved at ændre på HentHjemmeside.java til at spørge 'localhost' på port 8001 eller ved i Netscape at åbne adressen http://localhost:8001/xxx.html