___L _

Werbung
3
Verbindungslose Kommunikation mit UDP
Das User Datagram Protocol (DDP) stellt grundlegende Punktionen zur Verfügung, um mit geringem Aufwand Daten zwischen
kommunizierenden Prozessen austauschen zu können. UDP ist
als Transportprotokoll der dritten Schicht im TCP/IP-Schichtenmodell zugeordnet und nutzt den Vermittlungsdienst IP.
3.1
Das Protokoll UDP
DDP ist ein verbindungsloses Protokoll. d. h. es bietet keinerlei
Kontrolle über die sichere Ankunft versendeter Datenpakete, so
genannter Datagramme.
DDP ist im RFC (Request for Comments) 768 der IETF (Internet
Engineering Task Force) spezifiziert (siehe auch http://www. i etf.
org/rfc/rfc768.txt).
Datagramme müssen nicht den Empfänger in der Reihenfolge Datagramm
erreichen, in der sie abgeschickt werden. Datagramme können
verloren gehen, weder Sender noch Empfänger werden über den
Verlust informiert. Fehlerhafte Datagramme werden nicht nochmals übertragen.
Bild 3.1 zeigt den Aufbau des UDP-Datagramms. das in ein IPv4Paket eingebettet ist.
-----r-
•
-
,
...
4-
IPv4-Kopfteil
-
UDP-Kopftei I
---+----
UDP-Nutzdaten
-----*-----
IP-Adresse des Senders
IP-Adresse des Empfängers
...
-T-----20 Byte
_ _L _
--r----0- 40 Byte
Portnummer
des Senders
Portnummer
des Empfängers
Länge des Datagramms
Prüfsumme
Nutzdaten
Bild3.!·
__J _
8 Byte
Aufbau des UDPDatagramms
3
100
Verbindungslose Kommunikation mit UDP
Der UDP-Kopfteil enthält vier 16 Bit lange Felder,
•
die Portnummer des Senders,
•
die Portnummer des Empfängers,
•
die Gesamtlänge des UDP-Datagramms und
•
die Prüfsumme.
Darauf folgen dann die eigentlichen Nutzdaten des Datagramms.
Die Maximallänge eines UDP-Datagramms ist begrenzt. Anwendungen sollten nicht mehr als 508 Byte Nutzdaten in einem
Datagramm versenden, um Probleme infolge einer evtl. nötigen
Fragmentierung des IP-Pakets durch Router zu vermeiden.
UDP ist ein einfaches Mittel, um Nachrichten, die keine zuverlässige übertragung erfordern. zu versenden. UDP hat gegenüber
TCP den Vorteil eines viel geringeren Kontroll-Overheads (8 Byte
bei DDP. 20 Byte bei TCP).
UDP-Anwendungen
Einige bekannte Anwendungen, die UDP nutzen, sind:
•
das Domain Name System (DNS) zur automatischen Konvertierung von Domain-Namen (Rechnernamen) in IP-Adressen
und umgekehrt.
•
das Simple Network Management Protocol (SNMP) zur Verwaltung von Ressourcen in einem TCP/IP-basierten Netz,
•
das Trivial File Transfer Protocol (TFTP). das einen einfachen
Dateitransferdienst zum Sichern und Laden von System- und
Konfigurationsdateien bietet,
•
das Dynamic Host Configuration Protocol (DHCP) zur dynamischen Zuweisung von IP-Adressen.
Die unidirektionale übertragung von Video- und Audiosequenzen zur Wiedergabe in Echtzeit (Multimedia Streaming) ist
besonders zeitkritisch. Der gelegentliche Verlust eines Datenpakets kann aber toleriert werden. Hier ist UDP sehr gut geeignet.
3.2
DatagramSocket und DatagramPacket
Java-Programme nutzen so genannte Sockets als Programmierschnittstelle für die Kommunikation über DDP/IP und TCP/IP.
Sockets stellen die Endpunkte einer Kommunikationsbeziehung
zwischen Prozessen dar.
Ein UDP-Socket wird an eine Portnummer auf dem lokalen
Rechner gebunden. Er kann dann Datagramme an jeden beliebigen anderen DDP-Socket senden und von jedem beliebigen
UDP-Socket empfangen.
3.2
DatagramSocket und DatagramPacket
Rechn er A
101
Rechner B
Bild32·
UDP-Sockets
Client
Server
1/
IUDP-SoCke:Y
IP 10.108.105.95
Port 3963
IP 10.108.105.96 _
Port 50000
I
H
UDP-Socket
I
I
Die Klasse java. net. DatagramSocket repräsentiert einen UDP- DatagramSocket
Socket zum Senden und Empfangen von UDP-Datagrammen.
Ein DDP-Socket muss an einen Port des lokalen Rechners gebunden werden. Hierzu stehen Konstruktoren zur Verfügung:
DatagramSocket( ) throws Socket Except ion
erzeugt einen UDP-Socket und bindet ihn an einen verfügbaren
Port des lokalen Rechners.
DatagramSocket(int port) throws Socket Exception
erzeugt einen UDP-Socket und bindet ihn an die Portnummer
port des lokalen Rechners. Hierdurch kann ein Server den Port,
den er nutzen möchte, festlegen.
Beide Konstruktoren können bei Fehlern im zugrunde liegenden
Protokoll die Ausnahme ja va. net. SocketExceptl on auslösen:
Socket Exceptlon ist Subklasse von java.lo. IO Exceptlon .
Die Klasse java. net. DatagramPacket repräsentiert ein UDP-Data- DatagramPacket
gramm.
Der Konstruktor
DatagramPacket(byte[] buf. int l ength. Inet Addre ss address.
int port)
erzeugt ein UDP-Datagramm zum Senden von Daten. buf enthält
die Daten, addr ess ist die IP-Adresse und port die Portnummer
des Empfängers. Die Anzahl 1ength der zu übertragenden Bytes
muss kleiner oder gleich der Pufferlänge sein.
Der Konstruktor
DatagramPacket(byte[] buf. in t length)
erzeugt ein UDP-Datagramm zum Empfangen von Daten. buf ist
der Puffer. der die empfangenen Daten aufnimmt. 1ength legt
fest, wie viele Bytes maximal gelesen werden sollen. l engt h muss
kleiner oder gleich der Pufferlänge sein.
3
102
Verbindungslose Kommunikation mit UDP
Wendet man auf dieses Paket die Methoden setAdress und setPort (siehe weiter unten) an, so kann es auch gesendet werden.
send
Die DatagramSocket-Methode
void send(DatagramPack et p) t hr ows IOExcept i on
sendet ein UDP -Datagramm von diesem Socket aus.
receive
Die DatagramSocket-Methode
vOl d rece;ve(DatagramPacket p) throws IOExcept l on
empfängt ein UDP-Datagramm von diesem Socket. p enthält die
Daten sowie die IP-Adresse und die Portnummer des Senders.
Die Methode blockiert so lange, bis ein Datagramm empfangen
"WUrde.
Bild 3-3 zeigt den Ablauf zum Senden eines Datagramms in Form
eines UML-Sequenzdiagramms.
Bild3']·
Datagramm senden
Anwendung
:DatagramSocket
I
send(packet)
Weitere DatagramPacket-Methoden
Weitere DatagramPacket-Methoden sind:
byte[] getData ()
liefert den Datenpufferinhalt.
i nt getLength ()
liefert die Länge der Daten, die empfangen wurden bzw. gesendet werden sollen.
Inet Address getAddress()
liefert die (entfernte) IP-Adresse des Senders (beim empfangenen
Datagramm) bzw. des Empfängers (beim zu sendenden Datagramm).
3.3
Ein Echo-Server und -Client
103
i nt getPort()
liefert die (entfernte) Portnummer des Senders (beim empfangenen Datagramm) bzw. des Empfängers (beim zu sendenden
Datagramm).
void setData (byte[] buf)
setzt den Datenpuffer des Datagramms.
voi d setLength(int leng th)
bestimmt die Anzahl Bytes. die gesendet werden sollen bzw. die
maximale Anzahl Bytes. die empfangen werden sollen. 1ength
muss kleiner oder gleich der Pufferlänge des Datagramms sein.
voi d setAddress ( InetAddress address)
setzt die IP-Adresse des Rechners, an den das Datagramm gesendet werden soll.
void setPort(int port)
setzt die Portnummer, an die das Datagramm gesendet werden
soll.
In allen Beispielen dieses Kapitels ist die Bearbeitungszeit des
Servers nach Eintreffen eines Pakets relativ kurz. Deshalb ist eine
iterative Implementierung (Paket empfangen - Anfrag e bearbeiten - Paket senden) ausreichend.
Bei längeren Bearbeitungszeiten sollten für die Bearbeitung und
das Senden der Antwort zu einer Anfrage Threads benutzt werden (parallele Implementierung). um die durchschnittliche Wartezeit eines Clients zu reduzieren.
3.3
Ein Echo-Server und -Client
Das erste Programmbeispiel ist eine einfache Client-ServerAnwendung. die den Umgang mit den Methoden des vorigen
Abschnitts zeigen soll.
Der Client schickt einen Text, den der Server als Echo an den Programm3.l
Absender zurückschickt.
lmport java net. DatagramPacket;
lmport java net. DatagramSocket;
public class EchoSer ver (
pri vate static final int BUFSIZE
EchoServer
~
508;
public static void main(String[] args) throws Except i on (
int port ~ Int eger .par selnt (ar gs [O] ) ;
3
104
Verbindungslose Kommunikation mit UDP
// Socket an Port binden
DatagramSocket socket ~ new DatagramSocket(port);
// Pakete zum Empfangen bzw. Senden
DatagramPacket packet In ~ new DatagramPacket(
new byte[BUFSIZEJ. BUFSIZE);
DatagramPacket packetOut ~ new DatagramPacket(
new byte[BUFSIZEJ. BUFSIZE);
System. out. pri nt 1n( "Server gestartet ... ");
whi 1e (true) (
// Paket empfangen
socket.recelve(packetIn);
System. out. pri nt 1n("Recei vcd: "
+ " bytes");
+
packet! n. getLength()
// Daten und Länge lm Antwortpaket spelchern
packetOut.setData(packetIn.getData());
packetOut.setLength(packetIn.getLength());
// Zieladresse und Zielport im Antwortpaket setzen
packetOut.setAddress(packetIn.getAddress());
packetOut.setPort(packetIn.getPort());
// Antwortpaket senden
socket.send(packetOut);
Bild3.4·
Echo-Dienst
From: 10.108.105.95
Ta:
10.108.105.96
EchoClient
IP: 10.108.105.95
Port: 3963
IP:
10.108.105.96
Port: 50000
From: 10.108.105.96
Ta:
10.108.105.95
EchoServer wird mit dem Parameter Portnummer aufgerufen.
Zu Beginn wird ein UDP-Socket erzeugt und an die vorgegebene
Portnummer gebunden. Es werden zwei Datagramme zum Ernp-
3.3
105
Ein Echo-Server und -Client
fangen bzw. Senden von Daten mit der Pufferlänge 508 Byte
erzeugt. In einer Endlos-Schleife werden Daten empfangen und
gesendet. Nutzdaten und Datenlänge sowie IP-Adresse und Portnummer werden aus dem empfangenen Paket gelesen und in
das zu sendende Paket übertragen.
Der Server kann über Tastatur mit Strg+C abgebrochen werden.
Das Programm EchoCll ent sendet ein Datagramm an den Server. EchoClient
Neben dem Hostnamen und der Portnummer des Servers werden die Nutzdaten des Datagramms als weiterer Parameter beim
Aufruf mitgegeben.
Erhält der Client nicht innerhalb von zwei Sekunden eine Antwort vom Server, wird eine Ausnahme ausgelöst und das Programm beendet.
Diese Zeitsteuerung wird durch Aufruf der folgenden DatagramSocket-Methode erreicht.
vOld setSoTimeout(lnt tl meout) throws SocketExceptlon
setzt ein Timeout in Millisekunden. recel ve für diesen Socket
blockiert höchstens ti neout Millisekunden und löst dann die
Ausnahme java. net. SocketTl meoutExceptl on aus. Wird tlmeout =
o gesetzt, so wird die Timeout-Steuerung deaktiviert. Socket Tl meoutExceptlon ist Subklasse von java.l o. Interrupted IOExceptl on.
int getSoTimeout() throws SocketException
liefert die Timeout-Angabe.
lmport
lmport
lmport
lmport
java
java
java
java
net. DatagramPacket;
net. DatagramSocket;
net. InetAddress;
net SocketTl meoutExceptlon;
public class EchoClient (
private static final int BUFSIZE
private static final int TIMEOUT
~
~
508;
2000;
public static void main(String[] args) throws Exception {
try (
String host ~ args[O];
int port ~ Integer.parse lnt(args[I]);
byte[] data ~ args[2].getBytes();
// Socket wlrd an anonymen Port gebunden
DatagramSocket socket = new DatagramSocket();
// Maximal TIMEOUT Millisekunden auf Antwort warten
socket.setSoTi meout(TIMEOUT);
3 Verbindungslose Kommunikation mit UDP
106
// Paket an Server senden
Inet Address addr ~ Inet Address getByName(host);
DatagramPacket packetOut ~ new DatagramPacket(data,
data,length, addr, port);
socket,send (packetOut);
// Antwortpaket empfangen
DatagramPacket packet In ~ new DatagramPacket(
new byte[BUFS IZ EJ, BUFS IZ E);
socket.recelve(packet In);
Str ing received ~ new String(packet In getData(), 0,
packet In,getLength());
System. out. pr i nt l n( "Recel ved: " + rec el ved ) ;
socket,close();
catch (SocketTi meoutException e) (
System,err,println("Timeout; " + e getMessage() );
3.4
Feste Verbindungen
Die Klasse Dat agr amSocket enthält eine Methode, die es ermöglicht, die Adresse, an die Datagramme gesendet werden bzw.
von der Datagramme empfangen werden, gezielt auszuwählen
und alle anderen Datagramme zu verwerfen:
vOld connect( InetAddress address, i nt port)
Datagramme können nur an diese IP-Adresse/Portnummer gesendet bzw. von dieser IP-Adresse/Portnummer empfangen werden,
voi d disconnect()
hebt die durch connect hergestellte Restriktion auf,
Mit den beiden DatagramSocket-Methoden
Inet Address getlnetAddress() und
i nt getPort ()
können die IP-Adresse bzw. die Portnummer, die in connect
verwendet "WUrden, abgefragt werden. Wurde connect nicht benutzt, wird null bzw. - I geliefert,
Programm 3.2
Der Client Sender schickt kurze Texte aus einer Datei als Datag ramme an den Server. Der Server Recel ver zeigt die empfangenen Daten auf dem Bildschirm an. Er soll nur Datagramme,
die von einer bestimmten IP-Adresse und Portnummer aus ge-
3.4
Feste Verbindungen
107
sendet "WUrden, empfangen können. Zu diesem Zweck wird der
Server mit drei Parametern aufgerufen:
•
lokale Portnummer,
•
IP-Adresse/Rechnemame des Client und
•
Portnummer des Client,
lmport java net.DatagramPacket;
lmport java net.DatagramSocket;
lmport java net.InetAddress;
public class Receiver (
private static final int BUFSIZE
Receiver
~
508;
public static void main(String[] args) throws Exception (
int port ~ Integer.parselnt(args[O]);
String remoteHost ~ args[I];
int remotePort ~ Int eger .parse lnt (args [2] ) ;
OatagramSocket socket
~
new OatagramSocket(port);
// Es werden nur Datagramme dleser Adresse
// entgegengenommen
socket.connect( InetAddress.getByName(remoteHost).
remotePort) ;
DatagramPacket packet = new DatagramPacket(
new byte[BUFSIZE]. BUFSIZE);
whi 1e (true) (
socket.recelve(packet);
String text ~ new String(packet getOata(). O. packet
.getLength ());
System.out.println(packet.getAddress().getHostAddress()
+ "" " + packet.getPort() + " > " + text);
Beim Client Sender wird der DDP-Socket an eine explizit vorgegebene Portnummer gebunden. die beim Aufruf des Programms
als Parameter mitgegeben wird.
lmport
lmport
lmport
lmport
lmport
java.lo.BufferedReader;
java.lo.FlleReader:
java net.DatagramPacket;
java net.DatagramSocket;
java net.InetAddress;
Sender
3
108
Verbindungslose Kommunikation mit UDP
public class Sender (
private static final int BUFSIZE
~
508;
public static void main(String [] args) throws Exception (
int localPort ~ Integer.parselnt(args[O]);
String host ~ args[I];
int port ~ Integer.parselnt(args[2]);
// Socket wlrd an vorgegebenen Port gebunden
OatagramSocket socket ~ new OatagramSocket(localPort);
InetAddress addr ~ InetAddress.getByName(host);
DatagramPacket packet = new OatagramPacket(
new byte[BUFSIZE]. BUFSIZE. addr. port);
BufferedReader in ~ new BufferedReader(
new Fi1eReader("ei ngabe.t xt ") ) ;
Strlng I i ne ;
whi 1e ((l i ne ~ in. readLi ne()) ! ~ null)
byte[] data ~ line.getBytes();
packet.setOata(data);
packet.setLength(data length);
socket.send(packet);
in.close();
socket.close();
Aufrufbeispiel
Aufruf des Serverprogramms.
start java -cp bin Receiver 50000 localhost 40000
Es können nur Datagramme von 1oca1hast mit Portnummer
40000 empfangen werden.
Aufruf des Clientprogramms auf demselben Rechner;
java -cp bin Sender 40000 localhost 50000
Der Socket des Clients ist an die Portnummer 40000 gebunden.
Wird hier beim Aufruf statt 40000 z: B. 30000 angegeben, so ignoriert der Server die vom Client gesendeten Datagramme.
3.5 Online-Unterhaltung
3.5
109
Onllne·Unterhaltung
Mit dem folge nde n Programm Talk kö nnen zwei Benut ze r an
versch iedene n Rec hne rn ei ne Unte rhaltung o nline füh ren.
~
bl<-Hugo
, ~
Ha l l o , wi e geht' s?
11
a n ke , g an z g u t!
u
,
Bild 3.5 ,
I
UtUerbaltung
,- "
l*i T~ · EwoI
onune-
U
,
11 -
Dank e , g an z gut!
» er rc ,
"
.>0 ge ht ' s ?
=
Benutze r "H ugo " sitzt a m Rechner A OP-Adresse 10.108.105.95) , SZenario
Benutzer "Emil" a m Rechner B (IP-Adresse 10.108.105.96) .
Benutze r "H ugo" ruft das Programm wie folgt auf:
java -c p bi n Talk Hugo 50000 10 .108 .105 .96 50000
Benutzer "Emil" gibt das folgende Kommando ein:
java -cp bin Talk Emi 1 50000 10 .108 .105 .95 50000
Der UDP-Socket wird hier jeweils an die explizit vorg egebene
lokal e Polt nummer 50000 (zwe ite r Aufrufparameter) ge bunden.
Zum Test kann das Programm auch zweimal auf demselben
Rec hner (localhost) gestartet we rden. Alle rdings mü ssen da nn
die Po rtnumme rn unte rschiedlich sei n:
j ava -cp bi n Talk Hugo 40000 localh os t 50000
jeve -cp bin Talk Emi 1 50000 localhost
4‫סס‬oo
3
110
Programm 33
lmport
lmport
import
import
import
import
import
import
import
import
import
i mport
i mport
ja va
ja va
ja va
ja va
ja va
ja va
ja va
ja va
ja va
java
java
java
java
import
import
import
import
import
import
ja vax.swing
ja vax.swing
javax.swing
javax.swing
javax.swing
ja vax.swing
Verbindungslose Kommunikation mit UDP
awt Borderlayout;
awt Container;
awt Event Queue ;
awt Fl owLayout ;
awt Fant ;
awt event.ÄctionEvent;
awt event .Act i onLi ste ner ;
awt event. WindowAdapter;
awt.event. WindowEvent;
i o.IOExcept i on;
net.DatagramPacket;
net.OatagramSocket;
net. InetAddress;
JButton:
JFrame;
JPanel;
JScrollPane;
JTextArea;
JTextField;
public class Talk imp le rrents Actionlistener, Runnable (
private static f inal int BUFS IZ E ~ 508;
private DatagramSocket socket;
prlvate DatagramPacket packetOut;
private JTextField input;
prl vate JTextArea output;
public static voi d main(String [J args) {
if (args,length !~ 4) (
System.err.prl ntln("java Talk <user> <localPort> "
"<relTDte Host> <remotePort>");
+
Systeniex i t.C l ):
JFrame frame
=
new JFrame( );
try (
new Talk(args, frame);
catch (Exception e) (
System,err,println(e);
Systemex i t.C l ).
fra rre pack();
fra me setVisible(true);
public Talk(String[J args, JFrame fra me) throws Exception (
String user ~ args[OJ;
int localPort ~ Int eger parse Int(args[IJ);
3.5 OnIine-Unterhaltung
111
String remoteHost ~ args[2J;
int remotePort ~ Int eger .parse lnt (args [3J ) ;
InetAddress.getByName(
InetAddress remoteAddr
remoteHost) ;
~
frame.setTitle("Talk
"+
user);
socket ~ new DatagramSocket(localPort);
packetOut ~ new DatagramPacket(new byte[BUFSIZEJ. BUFSIZE.
remoteAddr. remotePort);
frame.addWindowListener(new WindowAdapter() (
public void windowClosing(WindowEvent e) {
i f (socket ! ~ null)
socket. cl ose () ;
System. exi t( 0) ;
}
}) ;
Contalner c
JPanel panel
frame.getContentPane();
=
~
new JPanel(new FlowLayout(FlowLayout.LEFT.
2. 2));
input ~ new JTextField(40);
input. setF ont (new Font("11mospaced". Font. PLAI N. 18));
pane1. add(input) ;
JButton send ~ new JButton("Senden");
send.addActionListener(this);
pane1. add(send);
c.add(panel. 8orderLayout.NORTH);
output ~ new JTextArea(IO. 45);
output.setFont(new Font("Monospaced". Font.PLAIN. 18));
output.setLineWrap(true);
output.setWrapStyleWord(true);
output.setEdi table(false);
c.add(new JScrollPane(output). BorderLayout.CENTER);
// Thread zum Empfangen von Nachrichten starten
Thread t ~ new Thread(this);
t.start();
public void run() (
OatagramPacket packetIn ~ new OatagramPacket(
new byte[BUFSIZEJ. BUFSIZE);
whi 1e (true) {
try (
receive(packetIn);
112
3
Verbindungslose Kommunikation mit UDP
catch (I OExcept i on e) (
break;
prl vate vOl d recel ve(DatagramPacket packet ln)
t hr ows IOExcept i on (
socket.recel ve(packet In);
final String text ~ new String(packet ln getData(), 0,
packet ln,ge tlength());
try (
Event Queue , i nvokel at er (new Runnable() (
public void run() (
output,append(text);
output . append("ln");
}
}) ;
catch (Exception e) (
public void actionPerformed(ActionEvent e) {
try (
byte[] data ~ input,getText(),getBytes();
packetOut.setData(data) ;
packetOut,setlength(data,l ength);
socket,send(packetOut);
catch ( IOException ex)
System,err,pr i ntln(ex);
Im Konstruktor werden zunächst IP-Adressen bestimmt, der
UDP-Socket an die vorgegebene lokale Portnummer gebunden
und ein Paket zum Senden der eingegebenen Daten erstellt.
Beim Schließen des Fensters wird der Socket geschlossen. Textfeld, Button und Textfläche werden erzeugt und platziert sowie
das aktuelle Objekt als Acti onl i stener beim Button registriert.
Schließlich wird ein Thread, der Datagramme empfängt (siehe
run-Methode), erzeugt und gestartet.
Innerhalb der run-Methode werden in einer Endlos-Schleife die
Daten empfangen und in der Textfläche angezeigt. Die DatagramSocket-Methode recel ve blockiert so lange, bis ein Datagramm
empfangen wurde, Die Ausgabe des Textes erfolgt in der runMethode eines Runnab1e-Objekts r, das mittels Event Queue ,
3.6
Punkt-zu-Mehrpunkt-Verbindungen
113
lnvokeLater(r) an den Ereignis-Dispatcher, der für die Aktualisierung der Benutzungsoberfläche verantwortlich ist, zur Ausführung weitergeleitet wird.
Beim Drücken des Buttons "Senden" werden die Daten des Eingabefeldes in einem Datagramm an die Zieladresse gesendet.
3.6
Punkt-zu-Mehrpunkt-Verbindungen
Bisher haben wir in diesem Kapitel ausschließlich Punkt-zuPunkt-Verbindungen (Unicast) betrachtet. Unter Multicast versteht man eine übertragung von einem Teilnehmer zu einer
Gruppe von Teilnehmern (Punkt-zu-Mebrpunkt-Verbindung).
Der Vorteil dieses Verfahrens liegt darin. dass gleichzeitig Pakete
über eine einzige Adresse an mehrere Teilnehmer gesendet werden. Die Vervielfältigung der Pakete findet nicht bereits beim
Sender statt, sondern erst an jedem Verteiler auf dem übertragungsweg. So wird Multicasting insbesondere zur übertragung
von Audio- und Videosträmen eingesetzt, um die Netzbelastung
zu reduzieren.
on e-to-many
=
Dalagramm
,ro
~
Multicast-Gruppe
228.5.6.7
Q~
Im Internet werden für das Multicasting die IP-Adressen der
Klasse D verwendet 224.0.0.0 - 239.255.255.255
Eine Multicast-Gruppe wird durch eine Adresse dieses Bereichs
(Multicast-Adresse) und eine UDP-Portnummer repräsentiert. Die
Adresse 224.0.0.0 ist reserviert und sollte nicht benutzt werden.
Teilnehmer können jederzeit einer Multicast-Gruppe beitreten
oder diese wieder verlassen. Wird eine Nachricht an eine Multicast-Gruppe gesendet, erhalten alle Gruppenteilnehmer diese
Nachricht, sofern sie sich im Time-to-Live-Bereich des Pakets
befinden. Das Feld Time-ta-Live (TTL) im Header eines IP-Pakets
gibt an, wie lange ein Paket im Internet verbleiben darf. Es handelt sich um einen Zähler, der von jedem Router, den das Paket
passiert, um 1 dekrementiert wird. Bei einem Wert von 0 wird
Bild 3,6.'
Mu!ticasting
3 Verbindungslose Kommunikation mit UDP
114
das Paket zerstört. Die Reichweite der gesendeten Pakete kann
also durch die Angabe des Time-to-Live-Wertes eingeschränkt
werden.
MulticastSocket
Die Klasse ja va.net. Multi castSocket (Subklasse von DatagramSocket) wird zum Senden und Empfangen von MulitcastDatagrammen verwendet.
void setTimeToLive( i nt ttl) throws IOExcept i on
setzt den Time-To-Live-Wert. Zulässiger Wert, 0 <= ttl <= 255.
Voreinstellung ist 1void joinGroup(lnetAddress mc ast addr ) throws IOExcept i on
tritt der Multicast-Gruppe bei.
voi d leaveGroup( lnetAddress mcastaddr) throws IOExcept i on
verlässt die Multicast-Gruppe .
Ein Client, der ein Datagramm an eine Multicast-Gruppe sendet,
muss selbst nicht Teilnehmer dieser Gruppe sein.
Programm 3.4
Sender
Im folgenden Beispiel bilden zwei Receiver eine Multicast-
Gruppe (IP-Adresse, 228.5.6.7, Portnummer. 50000). Ein Sender
schickt in kurzen Abständen Nachrichten an diese Gruppe.
lmport
lmport
lmport
lmport
ja va
ja va
ja va
ja va
net DatagramPacket;
net DatagramSocket;
net. InetAddress;
util . Random;
public class Sender (
private static final int BU FS IZ E ~ 508;
pri vate stati c fi na1 i nt LOOPS ~ 10;
public static voi d main(String [J args) throws Except i on (
String host ~ args[OJ;
int port ~ Int eger .parsel nt (args[l J ) ;
OatagramSocket socket ~ new DatagramSocket();
Inet Address addr ~ Inet Address .get ByName(host );
DatagramPacket packet = new DatagramPacket(
new byte[BU FS IZ EJ. BU FS IZ E. addr. port );
for (int i ~ 0; i < LOOPS; i++)
Random random = new Random ();
int value = random.next Int () ;
byte[J data ~ String. valueOf (value).getBytes ();
packet.setOata(data);
packet.setLength(data length);
socket.send(packet);
3.6
Punkt-zu-Mehrpunkt-Verbindungen
115
Thread.sleep(3000);
lmport java net.DatagramPacket;
lmport java net.InetAddress;
lmport java net MultlcastSocket;
public class Receiver (
private static final int BUFSIZE
Receiver
~
508;
public static void main(String[] args) throws Exception
String id ~ args[O];
InetAddress group ~ InetAddress.getByName(args[I]);
int port ~ Integer.parselnt(args[2]);
System.out.prlntln("Recelver " + id);
MulticastSocket socket ~ new MulticastSocket(port);
socket. setTi !TeToli ve(I); / / begrenzt auf lokales Subnetz
socket. j oi nGroup (group) ;
OatagramPacket packetIn ~ new OatagramPacket(
new byte[BUFSIZE]. BUFSIZE);
whi 1e (true) (
socket.receive(packetIn);
String received ~ new String(packetln getOata(). O.
packetln.getlength());
System.out.println(received);
Zum Testen auf einem lokalen Windows-Rechner muss das Test
Netzwerk-Interface mit einer IP-Adresse konfiguriert sein. Ggf.
sind Firewall-Einstellungen anzupassen.
start java -cp bin Receiver I 228.5.6.7 50000
start java -cp bin Receiver 2 228.5.6.7 50000
java -cp bin Sender 228.5.6.7 50000
116
3
3.7
Verbindungslose Kommunikation mit UDP
Aufgaben
1.
Entwickeln Sie einen Server (Dayti rreSer ver) , der als Reaktion auf den Empfang eines "leeren" Datagramms die aktuelle
Systemzeit in Form einer Zeichenkette an den Sender zurückschickt. Programmieren Sie für den Test auch einen
passenden Client (Dayti rre Cl i ent), der maximal zwei Sekunden auf die Antwort des Servers wartet.
2,
Ein Client (M2sswertCl i ent) sendet in Abständen von 5 Sekunden Zufallszahlen mit Zeitpunktangaben an den Server.
Der Server (rvesswertServer) gibt diese Zahlen zusammen
mit der IP-Adresse des Senders am Bildschirm aus.
Beispiel,
10.108.105. 95 :39751 0:45:4648.72014957156734
10.108.105. 95 :39751 0:45:5148. 557565388620226
10.108.105. 95 :39751 0:45:56 70. 66274469656827
3.
Ein Server (QuoteServer) liefert zufallsgesteuert Zitate. Alle
Zitate befinden sich in einer Datei quotes.txt, die den folgenden Aufbau hat
Zitat (eine Zeile)
Autor des Zitats (eine Zeile)
Zitat (eine Zeile)
Autor des Zitats (eine Zeile)
Erhält der Server ein "leeres" Datagramm, so bestimmt eine
Zufallszahl, welches Zitat (mit Autor) an den Client gesendet
wird.
Programmieren Sie zum einen eine Anwendung mit grafischer Oberfläche (Quo teApp) und zum andem ein Applet
(QuoteApp1et) zur Anzeige des angeforderten Zitats.
4.
Erstellen Sie eine Variante des Programms 3.3 (Talk) für
eine Gruppenkommunikation mit Hilfe des MulticastingVerfahrens aus Kapitel 3.6. Aufrufparameter sollen sein:
User, Multicast-Adresse, Portnummer.
Herunterladen