programmera.net -> java -> normal för utskrift | info@programmera.net |
RMI Echo
1. Exemplet Echo: Översikt 2. Exemplet Echo: Serversidan 3. Exemplet Echo: Klientsidan 4. Echo 5. EchoImpl 6. EchoServer 7. EchoClient 8. Säkerhet |
1. Exemplet Echo: Översikt
Nu ska vi skriva ett exempel som tar inmatning från tangentbordet och skickar tillbaka samma text, med x mellan varje bokstav. Exemplet gör samma sak som exemplet echo på sidan om
Sockets . Här ges en sammanfattning på alla steg som man måste göra för att programmet ska fungera.
För att ladda hem hela applikationen, klicka på
rmiecho.zip . För att se koden till enskilda klasser, klicka på den klass du vill se:
2. Exemplet Echo: Serversidan
På serversidan behöver vi göra följande:
Vi börjar med att kompilera alla klasserna och skapa stubbarna. Jag lägger alla filerna i mappen /home/olle/java/rmiecho/server/src/, dessutom skapar jag en mapp där klasserna ska ligga /home/olle/java/rmiecho/server/classes/. Öppna ett terminalfönster och skriv alltså följande:
Vi ser att vi förutom de kompilerade klasserna också har fått en stubbe EchoImpl_Stub.class. Öppna ett nytt terminalfönster och starta registret:
[olle@dev1]$ cd /home/olle/java/rmiecho/server/src
[olle@dev1]$ javac -d ../classes/ Echo.java
[olle@dev1]$ javac -d ../classes/ EchoImpl.java
[olle@dev1]$ javac -d ../classes/ EchoServer.java
[olle@dev1]$ cd ../classes/
[olle@dev1]$ rmic EchoImpl
[olle@dev1]$ ls
Echo.class EchoImpl.class EchoImpl_Stub.class EchoServer.class
Registertjänsten skapas på servermaskinen. I detta fall startas en process som lyssnar på defaultporten 1099. Man kan specifiera en egen port om man vill. Öppna ett nytt termialföster och starta servern:
[olle@dev1]$ cd /home/olle/java/rmiecho/server/classes/
[olle@dev1]$ rmiregistry
Sökvägen /home/olle/java/rmiecho/classes/ är sökvägen till den mapp i operativsystemet där de kompilerade klasserna ligger, denna måste du ändra om du har en annan sökväg.
[olle@dev1]$ cd /home/olle/java/rmiecho/server/classes/
[olle@dev1]$ java -Djava.rmi.server.codebase=file:///home/olle/java/rmiecho/server/classes/ EchoServer
Echo Server is ready.
3. Exemplet Echo: Klientsidan
På klientsidan måste följande saker göras:
Vi skapar mappen /home/olle/java/rmiecho/client/src/ och /home/olle/java/rmiecho/client/classes/. Sen kopierar vi Echo.class och EchoImpl_Stub.class till classes-mappen (där klientens klasser ska ligga):
Vi kompilerar och testkör klienten med följande kommandon:
[olle@dev1]$ cd /home/olle/java/rmiecho/server/classes/
[olle@dev1]$ cp EchoImpl_Stub.class ../../client/classes/
[olle@dev1]$ cd /home/olle/java/rmiecho/server/src/
[olle@dev1]$ cp Echo.java ../../client/src/
Verkar funka.
[olle@dev1]$ cd /home/olle/java/rmiecho/client/src/
[olle@dev1]$ ls
EchoClient.java Echo.java
[olle@dev1]$ javac -d ../classes/ Echo.java EchoClient.java
[olle@dev1]$ cd ../classes/
[olle@dev1]$ ls
Echo.class EchoClient.class EchoImpl_Stub.class
[olle@dev1]$ java EchoClient
Object found!
hej alla
echo: hxexjx xaxlxlxax
ok
echo: oxkx
4. Echo
Echo ska finnas både på klienten och på servern.
Ett krav på gränssnittet är att det ärver av Remote.
import java.rmi.*;
public interface Echo extends Remote {
public String echo(String s) throws RemoteException;
}
5. EchoImpl
EchoImpl är den klass som vi vi ska använda från klienten.
Följande delar av EchoImpl är obligatoriska:
import java.rmi.*;
import java.rmi.server.*;
public class EchoImpl extends UnicastRemoteObject implements EchoInterface{
public Echo() throws RemoteException{
super();
}
public String echo(String s) throws RemoteException {
String res="";
for(int i=0; i<s.length(); i++)
res+=s.charAt(i)+"x";
return res;
}
}
6. EchoServer
EchoServer är den klass som kör i bakgrunden och tar emot förfrågningar från klienter.
Naming.rebind() utför själva registreringen av klassen i registret. En server kan registrera många klasser, men vi registrerar bara EchoImpl.
import java.rmi.*;
import java.rmi.server.*;
public class EchoServer{
public static void main (String[] argv) {
try {
Naming.rebind ("Echo", new EchoImpl());
System.out.println ("Echo Server is ready.");
} catch (Exception e) {
System.out.println ("Echo Server failed: " + e);
}
}
}
7. EchoClient
Med EchoClient testar vi EchoImpl från en annan dator. Är man lite försiktig kan man först testa EchoClient på servern. Då använder man localhost istället för IP-adress.
import java.rmi.*;
import java.rmi.server.*;
import java.io.*;
public class EchoClient{
public static void main (String[] argv) {
try {
// Get Echo
Echo echo = (Echo) Naming.lookup ("rmi://localhost/Echo");
System.out.println("Object found!");
// Use Echo
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
String userInput;
while ((userInput = stdIn.readLine()) != null) {
System.out.println("echo: " + echo.echo(userInput));
}
} catch (Exception e) {
System.out.println ("EchoClient exception: " + e);
}
}
}
8. Säkerhet
Det vanligaste problemet med RMI är strul med säkerheten. För att tillåta allt lägger du följande kod överst i main i din klientklass.
Denna deklarerar en ny RMISecurityManager som tillåter allt. Koden ser lite konstig ut eftersom vi har gjort en anonym inre klass (vilket man inte gör så ofta).
System.setSecurityManager (new RMISecurityManager() {
public void checkConnect (String host, int port) {}
public void checkConnect (String host, int port, Object context) {}
});