Netzwerkprogrammierung

Hinweis: Die Behandlung der Netzwerkprogrammierung ist nur im LK vorgesehen. Der nachfolgende Abschnitt gliedert sich nach den drei Klassen der Netzwerkbibliothek: Connection, Client und Server.

Die Klasse Connection

Objekte der Klasse Connection ermöglichen eine Netzwerkverbindung zu einem Server mittels TCP/IP-Protokoll. Nach Verbindungsaufbau können Zeichenketten (Strings) zum Server gesendet und von diesem empfangen werden.

TimeClient

Im folgenden Beispiel wird Kontakt zu einem öffentlichen Time-Server aufgenommen und ohne das Versenden einer eigenen Nachricht eine Nachricht des Servers (die aktuelle Zeit) abgewartet.

import netz.*;

public class TimeClient {

    public String getTime() {
        Connection con = new Connection("time.fu-berlin.de",13);
        return con.receive();
    }

}

EchoClient

Im Gegensatz zum vorherigen Beispiel wird zunächst eine eigene Nachricht zum (Echo-)Server geschickt, bevor erneut auf Antwort des Servers gewartet wird.

import netz.*;

public class EchoClient1 {

    Connection con;

    public void starteClient(String pIPAdresse, int pPort) {
        con = new Connection(pIPAdresse, pPort);
    }

    public String sendeNachricht(String pNachricht) {
        con.send(pNachricht);
        return con.receive();
    }

    public void beendeVerbindung() {
        con.close();
    }
}

Die Klasse Client

Objekte von Unterklassen der abstrakten Klasse Client ermöglichen Netzwerkverbindungen zu einem Server mittels TCP/IP-Protokoll. Nach Verbindungsaufbau können Zeichenketten (Strings) zum Server gesendet und von diesem empfangen werden, wobei der Nachrichtenempfang nebenläufig geschieht. Jede empfangene Nachricht wird einer Ereignisbehandlungsmethode übergeben, die in Unterklassen implementiert werden muss (vgl. Methode processMessage).

EchoClient

Das folgende Beispiel zeigt eine Umsetzung des Echo-Clients als Unterklasse der Klasse Client. Zu beachten ist hier das Überlagern der Methode processMessage.

import netz.*;

public class EchoClient2 extends Client {

    public EchoClient2(String pIPAdresse, int pPortNr) {
        super(pIPAdresse, pPortNr);
    }

    public void processMessage(String pMessage) {
        System.out.println(pMessage);
    }

    public void sendeNachricht(String pNachricht) {
        this.send(pNachricht);
    }
}

Die Klasse Server

Objekte von Unterklassen der abstrakten Klasse Server ermöglichen das Anbieten von Serverdiensten, so dass Clients Verbindungen zum Server mittels TCP/IP-Protokoll aufbauen können. Verbindungsannahme, Nachrichtenempfang und Verbindungsende geschehen nebenläufig. Auf diese Ereignisse muss durch Überschreiben der entsprechenden Ereignisbehandlungsmethoden reagiert werden (vgl. Methoden processNewConnection, processMessage und processClosingConnection).

EchoServer

Das fgolgende Beispiel zeigt eine Umsetzung eines Echo-Servers als Unterklasse der Klasse Server. Zu beachten ist hier das Überlagern der drei genannten Methoden.

import netz.*;

public class EchoServer extends Server {

  public EchoServer (int pPortNum) {
    super(pPortNum);
  }

  public void processNewConnection(String pClientIP, int pClientPort) {
      System.out.println("! Neue Verbindung " + pClientIP + ":" + pClientPort);
  }

  public void processMessage(String pClientIP, int pClientPort, String pMessage) {
     System.out.println(">>" + pClientIP + ":" + pClientPort + " : " + pMessage);
     this.send(pClientIP, pClientPort, pMessage);
  }

  public void processClosingConnection(String pClientIP, int pClientPort) {
      System.out.println("! Abmeldung Client " + pClientIP + ":" + pClientPort);
  }
}

RateServer

Das abschließende Beispiel setzt einen einfachen Zahlenraten-Server als Client-Server-Lösung mit beliebig vielen Mitspielern um.

import netz.*;
import java.util.*;

public class RateServer extends Server {
  private Random zufall;
  private int ratezahl;

  public RateServer(int pPortNr) {
    super(pPortNr);
    zufall = new Random();
    ratezahl = zufall.nextInt(1000)+1;
    System.out.println("Der Server ist gestartet. PortNr: "+pPortNr);
  }

  public void processClosingConnection(String pClientIP, int pClientPort) {
    System.out.println(""+pClientIP+" "+pClientPort+" hat sich abgemeldet.");
  }

  public void processMessage(String pClientIP, int pClientPort, String pNachricht) {
    try {
      int zahl = Integer.parseInt(pNachricht);
      if (zahl == ratezahl) {    
        send(pClientIP, pClientPort,pClientIP+" "+pClientPort+"+ok Herzlichen Glückwunsch");
        System.out.println("Gewinner: " + pClientIP + ":" + pClientPort);
        ratezahl = zufall.nextInt(1000)+1;
        sendToAll("Neues Spiel");
        System.out.println("Neues Spiel gestartet");
      } else {
        if (zahl < ratezahl) {
          send(pClientIP, pClientPort,"+ok "+zahl+" ist zu klein"); 
        } else {
          send(pClientIP, pClientPort,"+ok "+zahl+" ist zu gross"); 
        }
      }
    } catch (Exception e) {
      send(pClientIP, pClientPort, "-err Bitte Zahl zwischen 1 und 1000 schicken");
    }
    System.out.println(""+pClientIP+" "+pClientPort+" "+pNachricht);
  }

  public void processNewConnection(String pClientIP, int pClientPort) {
    send(pClientIP, pClientPort, "+ok Willkommen. "+pClientIP+" "+pClientPort);
    send(pClientIP, pClientPort, "Bitte Zahl schicken");    
  }

}

results matching ""

    No results matching ""