Kommunikation über Sockets, Java RMI

Werbung
Realisierung verteilter Anwendungen: Teil 2
Ralf Möller, FH Wedel
Inhalt heute:
Kommunikation über Sockets
Java Remote Method Invocation, RMI
Lernziele:
Verständnis eines Basisdienstes: Sockets (in Java)
Grundlage von „Middleware“-Architekturen:
Überblick über RMI
Verteilung und Kommunikation
 Kommunikationsprotokoll
 Beispiel: TCP/IP
 Schicht 4 (bzw. 3) des ISO/OSI
Referenzmodells
 Transport von Informationen über ein
Netzwerk
 Zwei Arten:
 TCP
 UDP
Application
Presentation
Session
Transport
Network
Data link
Physical
email s erv er
Desktop
computers
print and other servers
Web server
Local area
netw ork
email s erv er
File s erv er
print
other servers
the rest of
the Internet
router/firew all
TCP
Client
Server
Application
Application
Presentation
Presentation
Session
Transport
Session
Request
Input Stream
Transport
Output Stream
Result
UDP
Client
Server
Application
Application
Presentation
Presentation
Session
Request-Datagrams
Transport
Session
Transport
Result Datagrams
Adressierung und Abstraktion (in Java)
Adressierung eines Knotens (Computer)
IP-Adresse (z.B. 134.100.12.135) oder Name
Port (z.B. 8088)
Namensdienste: DNS
socket
any port
agreed port
socket
message
client
server
other ports
Internet address = 138.37.94.248
Internet address = 138.37.88.249
Internet name = vodka
Sockets (Server-Seite)
import java.net.*;
int port = 1234;
ServerSocket server = new ServerSocket(port);
while (true) {
System.out.println("Waiting for client ...");
Socket client = server.accept();
System.out.println("Client " +
client.getInetAddress() +
" connected."); }
Sockets (Client-Seite)
import java.net.*;
Socket server = new Socket("vodka", 1234);
System.out.println("Connected to " +
server.getInetAddress());
Eine Abstraktion: Ströme (streams) und Filter
By
te
Byte
te
By
OutputStream
Bo
o
l
e
an
Integer
ing
S tr
Ohne Filter
DataOutputStream
InputStream
BufferedOuputStream
InputStream
te
By
Byte
B
y
te
BufferedInputStream
OutputStream
DataInputStream
ing
St r
Integer
Bo
o
l
ea
n
Mit Filter:
Datenaufbereitung +
Pufferung
TimeServer
import java.net.*, java.io.*, java.util.*;
public class TimeServer {
Public static void main(String args[]) throws IOException {
int port = 1234;
ServerSocket server = new ServerSocket(port);
while (true) { System.out.println("Wait for client ... ");
Socket client = server.accept();
OutputStream out = client.getOutputStream();
Date date = new Date;
byte b[] = date.toString().getBytes();
out.write(b) } } }
TimeClient
import java.net.*, java.io.*;
public class TimeClient {
Public static void main(String args[]) throws IOException {
int port = 1234;
Socket server = new Socket("vodka", 1234);
InputStream in = server.getInputStream();
byte b[] = new byte[100];
int num = in.read(b);
String date = new String(b);
... } } }
TimeServer mit Filter
DataOutputStream out =
new DataOutputStream(
new BufferedOutputStream(
client.getOutputStream()));
Date = new Date;
out.writeUTF(date.toString());
out.flush();
UTF-8: Übertragungsformat für Zeichenketten (Unicode)
TimeClient mit Filter
DataInputStream in =
new DataInputStream(
new BufferedInputStream(
server.getInputStream()));
System.out.println("Server said: " +
in.readUTF());
MulticastSockets
 InetAddress group;
 MulticastSocket socket;
 group = InetAddress.getByName("226.1.3.5");
 byte[] buf = new byte[1000]
 socket.joinGroup(group); ...
 DatagramPacket dg =
new DatagramPacket(buf, buf.length(), group, port);
 socket.receive(dg);
 String message = new String(dg.getData());
 socket.send(dg);
Lehnen wir uns zurück
Ist durch das Design mit „Sockets“ und „Threads“
Transparenz gegeben?
Zugriffstransparenz (lokal vs. global)
Ortstransparenz
Nebenläufigkeitstransparenz
Replikationstransparenz
Fehlertransparenz
Migrationstransparenz
Performanz- und Skalierungstransparenz
Ein BeiSpiel: Simple Baseball
public class Bat {
public void play (Ball ball) { ball.hit(); }
public static void main (String args[]) {
Ball ball = new Ball();
Bat bat = new Bat();
bat.play(ball) } }
public class Ball {
public void hit() {
System.out.println("Ball has been hit.") } }
$ java Bat
Ball has been hit.
Transparenz bei der Socket-Architektur ?
+ Datei vs. (entfernter) Port (Ströme)
Binär, zeichenkettenbasiert, Filter für Primitivtypen
- Daten(de)kodierung schwierig zu programmieren
local
remote
invocation
A
B
C
local E
invocation
invocation
local
invocation
D
-> In C: Remote Procedure Call (RPC)
-> In OOP: Senden von Nachrichten an entfernte Objekte
-> In Java: Remote Method Invocation (RMI)
remote
invocation
F
Remote Method Invocation (RMI)
 Probleme:
Quasi-transparenter Aufruf von Methoden von Objekten auf
verschiedenen virtuellen Maschinen
Referenzen auf Objekte eines Adreßraumes haben in einem
anderen (entfernten) Adreßraum keine Bedeutung
Speicherbereinigung (Garbage Collection)
 RMI – Ziele:
Vereinfachung der Entwicklung zuverlässiger
verteilter Anwendungen
Beibehaltung des Java-Sicherheitsmodells
Unterstützung von Unicast and Multicast
Die Architektur von RMI
Client vs. Server
Server veröffentlicht Schnittstelle
Registrierung vs.
Lokalisierung von
Servern
Registratur
(registry)
Namensdienste
Server: Konventionen bei der Programmierung
Klassenstruktur
java.rmi.RemoteObject
java.rmi.Remote
java.rmi.UnicastRemoteObject
MyServerInterface
extends
MyServer
implements
Das Beispiel mit RMI: der Server (1)
import java.rmi.*
public interface RemoteBall extends Remote {
public void hit() throws RemoteException;
}
Das Beispiel mit RMI: der Server (2)
import java.rmi.server.*;
public class Ball extends UnicastRemoteObject
implements RemoteBall {
public Ball() throws RemoteException {
super(); }
public void hit() {
System.out.println("Ball has been hit."); }...
Das Beispiel mit RMI: der Server (3)
 ...
 public static void main(Sting args[]) {
try {
Ball ball = new Ball();
Naming.rebind("Ball", ball);
} catch (Exception e) { e.printStackTrace(); }}}
vodka$ javac Ball.java; rmic Ball; rmirestristy; java Ball
Erzeugung von Stubs und Skeletons
rmic Ball(.class)
Erzeugen der Klasse Ball_Stub.class ...
... und der Klasse Ball_Skel.class
Stub wird auf Client-Seite benötigt
Bereitstellung als File oder ...
... Nachladen über das Netz (SecurityManager)
Das Beispiel mit RMI: der Client (1)
import java.rmi.*;
public class Bat {
Interface RemoteBall.java
muß beim Client vorhanden sein:
Statische Stellvertreter
public Ball ball;
public void play(RemoteBall ball) {
try { ball.hit(); }
catch (RemoteException e) {
System.out.println(e);
}
}
Das Beispiel mit RMI: der Client (2)
public static void main(String args[]) {
Bat bat = new Bat();
try { System.setSecurityManager(new
RMISecurityManager());
RemoteBall remoteBall =
(RemoteBall)
Naming.lookup("rmi://vodka.fh-wedel.de/Ball");
bat.play(remoteBall);
} catch (Exception e) { System.out.println(e); } } }
client$ java Bat
Ball has been hit.
Wo wird gedruckt?
Das Beispiel mit RMI: der Client (2)
public static void main(String args[]) {
Bat bat = new Bat();
try { System.setSecurityManager(new
RMISecurityManager());
RemoteBall remoteBall =
(RemoteBall)
Naming.lookup("rmi://vodka.fh-wedel.de/Ball");
bat.play(remoteBall);
} catch (Exception e) { System.out.println(e); } } }
client$ java Bat
server| Ball has been hit.
Nachrichten mit Parameter (1)
import java.rmi.*, java.rmi.server.*;
public interface RemoteBall extends Remote {
public void hit(Player p) throws RemoteException; }
public class Ball extends UnicastRemoteObject
implements RemoteBall {
public Ball() throws RemoteException {
super(); }
...
Nachrichten mit Parameter (2)
public void hit(int n) {
System.out.println("Ball has been hit by." +
" player " + n); }
public void hit(Player p) {
System.out.println("Ball has been hit by." +
p.name() + " from team " +
p.team()); } }
Nachrichten mit Parameter (3)
public class Player {
Was wäre, wenn "team"
ein Objekt wäre?
String name;
String team;
public Player(String playername, String teamname) {
name = playername;
team = teamname; }
public String name() { return name; }
public String team() { return team; }
}
Nachrichten mit Parameter (4)
Pass-by-Value von Objektstrukturen
"Kopiersemantik"
Änderungen auf der Zielseite sind nicht auf der
Senderseite sichtbar (und umgekehrt)!
Pass-by-Reference bei entfernten Objekten (Stubs)
"Zeigersemantik"
Details in:
Troy Brian Downing,
Java RMI: Remote Method Invocation,
Prentice Hall (1998).
Realisierung einer Callback-Kommunikation?
Server
Client auch als RMIServer implementieren!
Server kann dann Client
über normalen
Methodenaufruf
kontaktieren
Trennung zwischen
Server und Client wird
aufgehoben
Verteilte Müllbeseitigung (Garbage Collection)
Bei RMI wird nicht nur festgehalten, ob
Referenzen auf ein Objekt vorhanden sind,
sondern auch, von welcher VM aus.
Feststellung, ob ein Objekt noch benötigt wird
Details kommen später ...
Zusammenfassung: RMI
 Namensverwaltung für Objektreferenzen
 Senden einer Nachricht (synchrone Kommunikation)
 RMI übernimmt Parameter- und Ergebnistransfer
(Marshalling and Demarshalling)
 Umrechnung in externe Datenrepräsentation
 Wiederherstellung von Objektstrukturen
 In Java: Interface "serializable"
 RMIClassloader
 RMI und Heterogenität
 Kein Problem, solange die VM von Java verwendet wird
RMI und Sicherheit
Standardmäßig keine Verschlüss elung von Daten
Standardmäßig keine Authentifizierung
Kein Rechtesystem
Jeder kann die Registratur abfragen
Stubs/Skeletons können simuliert werden
Keine Versionskontrolle zwischen Stub und
Skeleton
Bevor alle davoneilen
Fortsetzung der Diskussion über Middleware ...
mit dem Thema CORBA und Sprachunabhängigkeit
... beim nächsten Mal.
Herunterladen