Java – programowanie w sieci java.net

Transkrypt

Java – programowanie w sieci java.net
Java – programowanie w sieci

java.net

RMI
Programowanie sieciowe
OSI
WARSTWA APLIKACJI (7)
WARSTWA PREZENTACJI(6)
DoD
Java
Warstwa aplikacji
(HTTP)
Warstwa aplikacji
(np. HTTP)
Transport
(gniazdka)
Transport
(TCP, UDP)
Sieć
(datagramy, adresy IP)
Sieć
(IP)
Dostęp do sieci
Połączenie
(Sterowniki urządzeń)
WARSTWA SESJI (5)
WARSTWA TRANSPORTU (4)
WARSTWA SIECIOWA (3)
WARSTWA ŁĄCZA DANYCH (2)
WARSTWA FIZYCZNA (1)
java.net
Klasy/interfejsy do
adresowania IP
● ustanawiania połączeń TCP
● wysyłania i otrzymywania datagramów via UDP
● lokalizacji i identyfikacji zasobów sieciowych
● identyfikacji
● autoryzacji
●
java.net -- adresowanie IP
●
Klasy do
adresowania IP
Ipv4 (32b)
i Ipv6 (128b)
public class MyDNS {
public static void main(String[] args)
throws Exception {
}
}
java.net.InetAddress a =
java.net.InetAddress.getByName(args[0]);
System.out.println(a);
java.net -- adresowanie gniazdek
●
Klasy do adresowania gniazdek
SocketAddress (abstrakcyjna)
InetSocketAddress
SocketAddress= new InetSocketAddress( “localhost”, 80 );
SocketAddress= new InetSocketAddress( “volt”, 8080 );
Gniazdka (1)
Port
Serwer
Żądanie
połączenia
Klient
Port
Serwer
Klient
Port
Gniazdko (socket) to
punkt końcowy
połączenia pomiędzy
dwoma programami
działającymi w sieci.
Gniazdko jest
przypięte do
określonego portu.
Gniazdka (2)
Strona klienta
Socket socket = null;
PrintWriter out = null;
BufferedReader in = null;
try {
socket = new Socket( args[0], Integer.parseInt( args[1] ));
out = new PrintWriter(socket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
} catch (UnknownHostException e) {
System.err.println("Don't know about host: " + args[0] );
System.exit(1);
} catch (IOException e) {
System.err.println("Couldn't get I/O for "
+ "the connection to: " + args[0] + " port " + args[1] );
System.exit(1);
} catch ( NumberFormatException e ) {
System.err.println( "Port no. must be”
“ an integer number - got " + args[1] );
System.exit(1);
}
Strona serwera
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket( Integer.parseInt(args[0]));
} catch (IOException e) {
System.err.println("Could not listen on port: "+args[0]);
System.exit(1);
} catch(NumberFormatException e ) {
System.err.println( "Port number!” );
System.exit(1);
}
Socket clientSocket = null;
try {
clientSocket = serverSocket.accept();
} catch (IOException e) {
System.err.println("Accept failed.");
System.exit(1);
}
PrintWriter out = new PrintWriter(
clientSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(
clientSocket.getInputStream()));
Ćwiczenie: połączenie TCP
●
Serwer
http://www.iem.pw.edu.pl/~jstar/MyServer.java
●
Klient
http://www.iem.pw.edu.pl/~jstar/MyClient.java
Datagramy UDP (1)
●
●
●
●
Tworzymy
gniazdko
Tworzymy
pakiet
Wysyłamy
Możemy
odebrać
odpowiedź
Datagramy UDP (2)
// Tworzymy gniazdko
DatagramSocket socket = new DatagramSocket();
// Szykujemy pakiet
byte[] buf = new byte[256];
InetAddress address = InetAddress.getByName(args[0]);
DatagramPacket packet =
new DatagramPacket(buf, buf.length, address, 4445);
// Wysyłamy go
socket.send(packet);
// Odbieramy odpowiedź
packet = new DatagramPacket(buf, buf.length);
socket.receive(packet);
// Wyciągamy z niej dane
String received = new String(packet.getData());
Datagramy UDP (3)
socket = new DatagramSocket(4445);
...
public void run() {
while (cośTam) {
try {
byte[] buf = new byte[256];
// Przyjmij żądanie
DatagramPacket packet =
new DatagramPacket(buf, buf.length);
socket.receive(packet);
// Adres nadawcy
InetAddress address = packet.getAddress();
int port = packet.getPort();
// Odpowiedz
buf= response( buf );
packet =
new DatagramPacket(buf, buf.length, address, port);
socket.send(packet);
Ćwiczenie: datagramy UDP
●
Serwer
http://www.iem.pw.edu.pl/~jstar/quotes.txt
http://www.iem.pw.edu.pl/~jstar/QuteServer.java
http://www.iem.pw.edu.pl/~jstar/QuoteServerThread.java
●
Klient
http://www.iem.pw.edu.pl/~jstar/QuoteClient.java
Dostęp do zasobów sieci
●
●
●
●
●
●
●
URI
URL
URLClassLoader
URLConnection
URLStreamHandler
HttpURLConnection
JarURLConnection
Połączenie URL (1)
Połączenie URL (2)
import java.net.*;
import java.io.*;
public class URLConnectionReader {
public static void main(String[] args) throws Exception {
URL goo = new URL("http://www.google.pl/");
URLConnection gc = goo.openConnection();
BufferedReader in = new BufferedReader(
new InputStreamReader(
gc.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null)
System.out.println(inputLine);
in.close();
}
}
Można też od razu tak:
import java.net.*;
import java.io.*;
public class URLRead {
public static void main(String[] args)
throws Exception {
URL url = new URL( args[0] );
InputStreamReader in = new InputStreamReader(
url.openStream());
String input= in.read();
System.out.println(input);
in.close();
}
}
URLe w Swingu
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.html.*;
...
editorPane.addHyperlinkListener( new HyperlinkListener() {
public void hyperlinkUpdate(HyperlinkEvent e) {
if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
JEditorPane pane = (JEditorPane) e.getSource();
if (e instanceof .HTMLFrameHyperlinkEvent) {
HTMLFrameHyperlinkEvent evt = (HTMLFrameHyperlinkEvent)e;
HTMLDocument doc = (HTMLDocument)pane.getDocument();
doc.processHTMLFrameHyperlinkEvent(evt);
} else {
try {
pane.setPage(e.getURL());
} catch (Throwable t) {
t.printStackTrace();
}
}
}
}
});
RMI (Remote Method Invocation):
mechanizm wywoływania metod klas
działających na innej maszynie
wirtualnej.
Co to jest RMI
RMI to API wspomagające tworzenie
rozproszonych aplikacji obiektowych
(Distributed Object Application)
● Aplikacja taka składa się zwykle z kilku (min. 2)
programów, działających na różnych
komputerach
● Najprostszy model to działający na jednym z
komputerów program-klient, który wywołuje
metody obiektów programu-serwera.
● RMI zapewnia mechanizm komunikacji klienta
z serwerem
●
Co to jest RMI
RMI
RMI
Internet
Wymagania
●
●
●
Lokalizacja zdalnych obiektów
Komunikacja ze zdalnymi obiektami
Przekazywanie kodu pośredniego
Rejestr
RMI
Klient
HTTP
RMI
Serwer
WWW
HTTP
HTTP
RMI
Serwer
Serwer
WWW
Mechanizm komunikacji
Klient
Namiastka
Odbiornik
Serwer
Namiastka i Obiorca
Odbiorca:
Namiastka:
● odtwarza parametry
● tworzy po stronie klienta
blok danych zawierający: ● lokalizuje obiekt
– opis wywoływanej
● wywołuje metodę
metody
● pobiera wynik (wyjątek)
– identyfikator zdalnego
● serializuje go
obiektu
● wysyła dane do
– parametry
namiastki
(serializowane)
● wysyła dane do serwera
● odbiera i rozpakowuje
wynik
Klient (przykładowy)
import java.rmi.Naming;
import java.rmi.RMISecurityManager;
public class ShowQuote {
public static void main(String args[])
throws Exception
{
// Bywa jeszcze SecurityManager
}
}
String url= "rmi://localhost:1313/Quoter";
Quoter quoter = (Quoter)Naming.lookup( url );
System.out.println(quoter.getQuote());
Interfejs zdalny
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface Quoter
extends Remote
{
}
public abstract String getQuote()
throws RemoteException;
Implementacja
(zdalnego interfejsu Quoter)
import java.rmi.*;
import java.rmi.server.*;
public class RMIQuoter
extends UnicastRemoteObject
implements Quoter {
public RMIQuoter()
throws RemoteException
{}
public String getQuote(){
return "Na razie nic mądrego";
}
}
Serwer
import java.rmi.Naming;
public class RMIServer
{
public static void main(String args[])
throws Exception
{
RMIQuoter rmiquoter = new RMIQuoter();
Naming.bind( "Quoter", rmiquoter);
System.out.println("Quoter ready.");
}
}
Wdrożenie
Rejestr
volt
Serwer
Klient
Quoter.class
RMIQuoter.class
RMIQuoter_Stub.class
RMIServer.class
Serwer
WWW
client.policy
Quoter.class
ShowQuote.class
max
Quoter.class
RMIQuoter_Stub.class
grant
{
permission java.net.SocketPermission
"*:1024-65355", "connect";
permission java.net.SocketPermission
"*:80", "connect";
};
Uruchomienie
Maszyna serwera:
$ rmiregistry &
$ java -Djava.rmi.server.codebase=http:/max/~jstar/rmi_down/
RMIServer &
Klient:
$ java -Djava.security.policy=client.policy ShowQuote volt
Serwer aktywowany
●
●
●
●
●
RMI pozwala tworzyć tanie środowiska
obliczeniowe o dużej mocy
Tworzenie i rejestracja obiektów zanim jakiś
klient zechce z nich skorzystać może być
nieefektywne
Serwery aktywowane są generowane na
żądanie klienta
Ze strony klienta wszystko wygląda tak samo
Po stronie maszyny-serwera działa program
aktywujący, który tworzy serwery na żądanie
Serwer aktywowany
import java.rmi.*;
import java.rmi.activation.*;
public class ActRMIQuoter extends Activatable
implements Quoter
{
String quote;
public String getQuote()throws RemoteException {
return "Na razie nic mÄdrego";
}
public ActRMIQuoter( ActivationID id,
MarshalledObject data )
throws RemoteException {
super( id, 0 );
quote= (String) data.get();
}
}
Aktywator
import ...
public class RMIActivator
{
public static void main(String args[]) throws Exception {
Properties props= new Properties();
props.put("java.security.policy", new File("server.policy").getCanonicalPath() );
ActivationGroupDesc grdesc= new ActivationGroupDesc( props, null );
ActivationGroupID agid= ActivationGroup.getSystem().registerGroup( grdesc );
String classURL= args.length == 0 ?
new File( "." ).getCanonicalFile().toURL().toString() :
args[0];
System.out.println( "Class URL=" + classURL );
ActivationDesc adsc= new ActivationDesc( agid, "ActRMIQuoter"
classURL, new MarshalledObject(“Cytat”) );
Quoter q= (Quoter)Activatable.register( adsc );
}
}
Naming.bind( "Quoter", q);
System.out.println("Quoter ready. Exiting");
Wdrożenie aktywatora
Klient
Rejestr
Serwer
volt
ActRMIQuoter.class
ActRMIQuoter_Stub.class
RMIActivator.class
rmid.policy
Quoter.class
server.policy
max
client.policy
Quoter.class
ShowQuote.class
grant
{
permission com.sun.rmi.rmid.ExecPermission
"${java.home}${/}bin${/}java";
permission com.sun.rmi.rmid.ExecOptionPermission
"-Djava.security.policy=*";
};
Serwer
WWW
Quoter.class
ActRMIQuoter_Stub.class
grant
{
permission java.security.AllPermission "", "";
};
Uruchomienie
Maszyna serwera:
$ rmiregistry \
-J-Djava.rmi.server.codebase=http:/max/~jstar/rmi_down/ &
$ rmid -J-Djava.security.policy=rmid.policy &
$ java RMIActivator http://max/~jstar/rmi_down/
Klient:
$ java -Djava.security.policy=client.policy ShowQuote volt
Ćwiczenia:
1.
Pobrać: http://www.iem.pw.edu.pl/~jstar/rmiclient.tgz,
skompilować i uruchomić klienta
Poeksperymentować z plikiem policy
2.
Pobrać: http://www.iem.pw.edu.pl/~jstar/rmiserver.tgz,
skompilować i uruchomić server
3.
Napisać i wdrożyć własną aplikację: klient wysyła do
serwera napis (np. imię), serwer odpowiada “Witaj <imię>

Podobne dokumenty