Netzwerkprogrammierung: Unterschied zwischen den Versionen

Aus SibiWiki
Zur Navigation springen Zur Suche springen
Zeile 43: Zeile 43:
# '''Connection.java''' wird genutzt, wenn '''der Server nur auf Anfragen des Clients reagiert''', wie z.B. bei Mailprotokollen (SMTP oder POP3).
# '''Connection.java''' wird genutzt, wenn '''der Server nur auf Anfragen des Clients reagiert''', wie z.B. bei Mailprotokollen (SMTP oder POP3).
# '''Client.java''' wird genutzt, wenn '''der Server von sich aus aktiv werden kann'''. Das ist z.B. bei einem Chat der Fall, denn hier muss der Server Nachrichten eines ''anderen'' Client von sich aus an alle Clients weiterleiten können.
# '''Client.java''' wird genutzt, wenn '''der Server von sich aus aktiv werden kann'''. Das ist z.B. bei einem Chat der Fall, denn hier muss der Server Nachrichten eines ''anderen'' Client von sich aus an alle Clients weiterleiten können.


=== Connection.java vs. Client.java in der Programmierung ===
=== Connection.java vs. Client.java in der Programmierung ===
Zeile 76: Zeile 77:
   }
   }
</code>
</code>


= Server-Programmierung =
= Server-Programmierung =

Version vom 28. März 2012, 10:03 Uhr


Allgemeines

Netzwerkprogrammierung beschäftigt sich mit der Entwicklung von verteilten Anwendungen.

Dabei kommuniziert zumeist ein Server mit mehreren Clients.


Best Practices für Netzwerk-Protokolle

Es gibt meines Wissens keine allgemeingültigen Best Practices für die Erstellung von Protokollen.

Diese Best Practices sind vor allem auf die zuverlässigen Protokoll-Erstellung im Zentralabitur zugeschnitten und so angelegt, dass sich Protokolle einfach mit Java auswerten lassen.

  1. Jeder Befehl wird mit einem einheitlichen Zeichen eingeleitet, z.B. mit "+" (für erfolgreiche Befehle) und "-" (für Fehlermeldung.)
  2. JEDE Übertragung zwischen Client und Server startet mit einem Befehl, d.h. auch z.B. das einfache Senden von Nachrichtentext.
  3. Jede Nachricht an den Server wird vom Server entweder bearbeitet oder es kommt eine Fehlermeldung zurück. Die möglichen Fehlermeldungen müssen im Protokoll festgehalten werden.
  4. Es gibt eine allgemeine Fehlermeldung für unbekannte Befehle.
  5. Jeder Befehl hat genau 5 Buchstaben, davon ist der erste ein Plus oder Minus. Das hilft Ihnen bei der Programmierung des Servers Befehle und Parameter auszuwerten:

 String befehl = pMessage.substring(0,4);
 String parameter = pMessage.substring(6);
 // wenn Sie mehrere Parameter haben:
 String[] parameterSplits = parameter.split[" "];



Client-Programmierung

Für die Client-Programmierung stehen im Zentralabitur die Schnittstellen Connection.java und Client.java zur Verfügung.

Connection.java vs. Client.java

Die Schnittstellen fürs Zentralabitur stellen zwei Klassen zur Verfügung, mit denen auf der Client-Seite gearbeitet werden kann:

  1. Connection.java hat die folgenden Methode, um Nachrichten vom Server zu empfangen:
    1. public String receive()
  2. Client.java hat die folgenden Methode, um Nachrichten vom Server zu empfangen:
    1. public void processMessage(String pMessage

Die einfachere (=mit weniger Möglichkeiten) ist die Klasse Connection.java. Diese beiden Klassen werden in unterschiedlichen Szenarien benutzt:

  1. Connection.java wird genutzt, wenn der Server nur auf Anfragen des Clients reagiert, wie z.B. bei Mailprotokollen (SMTP oder POP3).
  2. Client.java wird genutzt, wenn der Server von sich aus aktiv werden kann. Das ist z.B. bei einem Chat der Fall, denn hier muss der Server Nachrichten eines anderen Client von sich aus an alle Clients weiterleiten können.


Connection.java vs. Client.java in der Programmierung

  1. Connection.java wird als Attribut benutzt, z.B.:

 public class SMTPClient{
   private Connection verbindung;
   
   public SMTPClient(){
       //Verbindung zum Mailserver herstellen
       verbindung = new Connection("192.168.100.2", 25);
   }
   ....
 }

  1. Von Client.java dagegen wird eine Unterklasse gebildet, die die Fähigkeiten von Client.java erbt. Dabei muss die Methode public void processMessage(String pMessage) überschrieben werden, damit man auf die Nachrichten des Servers reagieren kann. Z.B.:

   public class ChatClient extends Client{
     public ChatClient(){
       //Konstruktor der Klasse Client aufrufen!
       //Dadurch wird die Verbindung zum (selbstprogrammierten) Chatserver hergestellt
       super("192.168.100.100", 4444);
     }
   public void processMessage(String pMessage){
     // jetzt das Protokoll abarbeiten 
     if(pMessage.startsWith("neu")){
        // usw.
     }
     // usw.
   }
 }

Server-Programmierung

Für die Server-Programmierung gibt es die Klasse Server.java. Genauso wie bei Client.java muss die eigene Klasse von Server.java erben, um die Fähigkeiten von Server.java zu übernehmen, z.B.:

 public class ChatServer extends Server{
   public ChatServer(){
     // Konstruktor der Klasse Server aufrufen!
     // Dadurch wird der Server erzeugt.
     super(4444);
   }

Wichtig ist, dass die Klasse ChatServer dann die folgenden Methoden überschreibt, um auf Ereignisse bei den Clients angemessen reagieren zu können:

  1. public void processMessage(String pClientIP, int pClientPort, int pMessage)
  2. public void processNewConnection(String pClientIP, int pClientPort)
  3. public void processClosedConnection(String pClientIP, int pClientPort)

Von sich aus kann der Server aktiv werden, indem er...

  1. einem Client eine Nachricht schickt: public void send(String pClientIP, int pClientPort, String pMessage)
  2. allen Clients eine Nachricht schickt: public void sendToAll(String pMessage)
  3. einen Client rausschmeißt: public void closeConnection(String pClientIP, int pClientPort)
  4. den Server zumacht: public void close()

Wichtige Methoden der Klasse String

Für die Verarbeitung der Nachrichten sind folgende Methoden der Klasse String wichtig:


int compareTo(String anotherString)

Vergleicht zwei Strings alphabetisch. Als Ergebnis kommt eine Zahl raus.

Die Zahl ist GRÖSSER 0: Der erste String ist im Alphabet NACH dem zweiten String.

 Beispiel: int ergebnis = "b".compareTo("a") // ergebnis ist GRÖSSER 0.

   Die Zahl ist KLEINER 0: Der erste String ist im Alphabet VOR dem zweiten String. 
 
 Beispiel: int ergebnis = "b".compareTo("bb") // ergebnis ist KLEINER 0.
   Die Zahl ist GLEICH 0: Die Strings sind genau gleich.
 Beispiel: int ergebnis = "b".compareTo("b") // ergebnis = 0.
 

boolean equals(Object anObject)

  Vergleicht zwei Strings.

 NIE == verwenden um Strings zu vergleichen!

 

boolean equalsIgnoreCase(String anotherString)

 Hier wird verglichen und Unterschiede bei der Groß- und Kleinschreibung werden ignoriert. 

 

String[] split(String trennzeichen)      

  Zerlegt einen String in Teile, die dann in einem Array gespeichert werden.
  Beispiel: String[] ergebnis = "Das ist ein Satz".split(" ");
  
    Dann hat ergebnis die Länge 4, und in jedem Eintrag von ergebnis steht ein Wort. 

 

boolean startsWith(String prefix)

   Testet, ob der String mit einem bestimmten prefix anfängt.

  Ist wichtig, um bei der Auswertung von Protokollen die Befehle abzufragen.

  String substring(int beginIndex)

   Gibt einen Substring zurück, der bei dem Buchstaben beginIndex anfängt.

  Beispiel: String nachricht = "ANALLE hallo".substring(7);
  nachricht enthält jetzt "hallo". (Die Buchstaben werden von 0 anfangend nummeriert!)


String substring(int beginIndex, int endIndex)        s.o.; es wird zusätzlich der letzte Buchstabe festgelegt.