Die Zeitdienste und ein eigener Server und Client
Ein Zeit-Server bietet Clients immer die aktuelle Server-Uhrzeit an. Wir halten uns hier an das Daytime Protocol, welches im RFC 867 beschrieben ist. Ein Server lauscht auf Port 13 nach UDP-Paketen10 und sendet dann die Antwort an den Sender, dessen Adresse er aus dem Paket nimmt. Im Gegensatz zu unseren bisher geschriebenen Programmen muss der Client erst ein Paket aufbauen, es senden und dann auf die Antwort warten. Der Server erwartet jedoch kein spezielles Anfrageformat. Er reagiert auf einen beliebigen Inhalt, da er diesen ohnehin verwirft. Die Zeichenkette vom Server muss kein spezielles Format besitzen, doch bietet sich hier eine Zeichenkette mit dem Format »Wochentag, Monat, Tag, Jahr, Zeitzone« an.
Da Client und Server ziemlich ähnlich aufgebaut sind, ist es eigentlich egal, mit welchem Teil wir beginnen. Sie unterscheiden sich wenig, da beide Daten empfangen und senden. Wenn wir einen Client für Zeitdienste programmieren, können wir den eingebauten Daytime-Server nutzen. Unter Unix ist dieser schon vorinstalliert. Unter Windows müssen wir den Dienst erst mit dem Zusatzprogramm Uatime32 aus den Socket-Programmen starten. Da wir aber gleich selber einen Server programmieren werden, lässt sich zum Testen auch ein Kapitel weiter schauen.
Die folgende Implementierung zeigt, wie ein Zeit-Server angesprochen wird. Dazu wird zunächst ein leeres Paket als Anfrage an den Server gesendet. Anschließend wird mit receive() auf das hereinkommende Paket gewartet. Wenn dieses kommt, dann liefert getData() eine Zeichenkette mit der Zeit.
import java.net.*;
class UDPTimeClient
{
public static void main( String args[] )
{
try
{
DatagramPacket packet;
while ( true )
{
// zunächst die Anfrage an den Server
byte data[] = new byte[1024];
InetAddress ia = InetAddress.getByName( "localhost" );
packet = new DatagramPacket( data, data.length, ia, 13 );
DatagramSocket toSocket = new DatagramSocket();
toSocket.send( packet );
// Jetzt vom Server was empfangen
DatagramSocket fromSocket = toSocket;
//new DatagramSocket();
packet = new DatagramPacket( data, data.length );
fromSocket.receive( packet );
String s = "Server" + //packet.getAddress() +
" am Port " + packet.getPort() +
" gibt mit die Zeit "+
new String( packet.getData() );
System.out.println( s );
fromSocket.close();
Thread.sleep( 1000 );
}
}
catch ( Exception e )
{
System.out.println( e );
}
}
}
Der Server liest aus dem Paket die IP-Adresse und Port-Nummer des Senders heraus und schickt ein Paket mit einer Zeiteinheit zurück. Das nachfolgende Programm wartet auf dem Port auf eine Anfrage und gibt die aktuelle Zeit einfach aus.
import java.net.*;
import java.util.*;
public class UDPTimeServer
{
public static void main( String args[] )
{
try
{
byte data[] = new byte[ 1024 ];
DatagramPacket packet;
DatagramSocket socket = new DatagramSocket( 13 );
while ( true )
{
// Auf Anfrage warten
packet = new DatagramPacket( data, data.length );
socket.receive( packet );
// Empfänger auslesen, aber Paketinhalt ignorieren
InetAddress adress = packet.getAddress();
int port = packet.getPort();
System.out.println( "Anfrage von " + packet.getAddress() +
" am Port " + packet.getPort() );
// Paket für Empfänger zusammenbauen
String s = new Date().toString() + "\n";
s.getBytes( 0, s.length(), data, 0 );
packet = new DatagramPacket(data,data.length,adress,port);
socket.send( packet );
Thread.sleep( 1000 );
}
}
catch ( Exception e )
{
System.out.println( e );
}
}
}