<1> <Network Programming> Part 5 확장된 Network Programming 기술 1. Remote Procedure Call 2. Remote Method Invocation 3. Object Request Broker
<2> <Network Programming> 2. Java RMI
<3> <Network Programming> 1. RMI 기초 (1) 분산컴퓨팅 소켓사용 저수준프로그래밍 사용하기어려움
<4> <Network Programming> 1. RMI 기초 (2) 분산컴퓨팅 분산객체사용 - RMI, CORBA 고수준프로그래밍 사용이편리
<5> <Network Programming> 1. RMI 기초 (3) RMI의장점 객체지향적. 프로그램작성및사용의용이성. 보안성. 기존시스템과통합. RMI 의기본적인목적 원격객체 (remote object) 의메소드를호출할수있는방법제공 원격객체 - 다른자바가상머신 ( 일반적으로다른컴퓨터에있는 ) 에서호출할수있는메소드를가지는객체 원격객체는 UnicastRemoteObject 클래스로부터상속받고, 원격인터페이스를임플리멘츠한다.
<6> <Network Programming> 1. RMI 기초 (4) 클라이언트와원격객체의관계 class A - 클라이언트 class B - 원격객체 ( 서버 ) 클라이언트 class A 의함수 a() 는원격객체 class B 의 b() 함수를호출.
<7> <Network Programming> 1. RMI 기초 (5) 자바 RMI 를이용한클라이언트 / 서버프로그램의작성단계
<8> <Network Programming> 1. RMI 기초 (6) RMI 프로그래밍절차 1. 원격인터페이스를정의한다. 2. 원격인터페이스를임플리멘츠하는원격객체 ( 서버 ) 를작성한다. 3. 원격객체를이용하는프로그램 ( 클라이언트 ) 을작성한다. 4. stub 과 skeleton 클래스를생성한다. 5. registry 를실행시킨다. 6. 서버와클라이언트를실행시킨다. 원격인터페이스 사용되는패키지 - java.rmi.remote, java.rmi.server 모든원격인터페이스는 Remote 인터페이스로부터상속받아야한다. Remote 인터페이스는메소드가선언되지않은인터페이스이다. public interface Remote { } RemoteObject - RMI 환경에서가장상위클래스
<9> <Network Programming> 1. RMI 기초 (7) RMI 구조이해 TCP/IP 바탕 3 계층구조 Stub/Skeleton 계층 - 마샬스트림 Remote Reference 계층 - 객체의특성파악 Transport 계층 - 네트워전송 RMI 에서원격객체의메소드를호출할때메소드의아규먼트와리턴값이네트워크를통해전달된다. 네트워크를통해전송할때메소드의아규먼트와리턴값을바이트스트림으로변경해서전달하게되는데, 이것을마샬스트림 (marshal stream) 이라고한다. 마샬스트림을만드는과정을마샬링 (marshaling) 이라고반대과정은언마샬링 (unmarshaling) 이라고한다.
<10> <Network Programming> 2. 자바 RMI 예제 (1) 1. sayhello() 라는메소드를갖는 Hello 라는원격인터페이스를정의한다. 예제 : Hello.java 1 package hello; 2 3 import java.rmi.*; 4 5 public interface Hello extends Remote { 6 7 public String sayhello() throws java.rmi.remoteexception; 8 9 } 참고 1) 원격인터페이스는 java.rmi.remote 인터페이스로부터상속받는다. 2) 원격인터페이스는 public 으로선언되어야한다.
<11> <Network Programming> 2. 자바 RMI 예제 (2) 2. Hello 인터페이스를임플리멘츠한 HelloImpl 이라는원격객체를만든다. 예제 : HelloImpl.java 1 package hello; 2 3 import java.rmi.*; 4 import java.rmi.server.*; 5 import java.net.*; 6 7 public class HelloImpl extends UnicastRemoteObject implements Hello { 8 9 public HelloImpl() throws RemoteException { super(); } 12 13 public String sayhello() throws RemoteException { return "Hello World"; 16 } 17 18 public static void main(string[] args) { 19 System.setSecurityManager(new RMISecurityManager()); 20 21 try { 22 HelloImpl h = new HelloImpl(); 23 Naming.rebind( rmi:/203.252.201.16:9999/hello", h); 24 System.out.println("Hello Server ready"); 25 } catch (RemoteException re) { 26 System.out.println("Exception in HelloImpl.main: " + re); 27 } catch (MalformedURLException mfe) { 28 System.out.println("MalformedURLException in HelloImpl.main" + mfe); 29 } 30 } 31 }
<12> <Network Programming> 2. 자바 RMI 예제 (3) bind 와 rebind rebind() 메소드와 bind() 메소드는원격객체를등록하는데사용되지만, 차이점은 bind() 메소드는동일한이름이이미등록되어있으면 java.rmi.alreadyboundexception 을발생시키지만, rebind() 는이미등록된객체대신에새로운객체로대치한다. 두메소드모두아규먼트로 RMI URL 와인스턴스이름이사용된다. RMI URL 은다음과같은형태로되어있다. 형태 rmi://host:port/object_name 따라서예제프로그램처럼간단히 hello 라고이름만기술한경우는 예 : Naming.rebind("rmi://localhost:1099/hello", h); 와동일하다. RMI는기본적으로 1099 포트를사용한다. 참고 1. 원격객체는원격인터페이스에선언되지않은메소드들도정의할수있지만원격인터페이스에선언되지않은메소드는클라이언트에서호출할수없다. 2. 원격객체의생성자와메소드들은 RemoteException을 throws해야한다.
<13> <Network Programming> 2. 자바 RMI 예제 (4) 컴파일하기 % javac -d. Hello.java HelloImpl.java 3. HelloImpl 원격객체를이용하는프로그램 ( 클라이언트 ) 을작성한다. 예제 : HelloClient.java 1 package hello; 2 3 import java.rmi.*; 4 5 public class HelloClient { 6 7 public static void main(string[] args) { 8 9 System.setSecurityManager(new RMISecurityManager()); 10 11 try {
<14> <Network Programming> 2. 자바 RMI 예제 (5) 12 Hello h = (Hello) Naming.lookup("rmi://203.252.201.16/hello"); 13 14 String message = h.sayhello(); 15 System.out.println("HelloClient: " +message); 16 } catch(exception e) { 17 System.out.println("Exception in main: "+ e); 18 } 19 } 20 } 4. rmic 를이용해서 stub 과 skeleton 클래스를만들고, jar 파일을만든다. % rmic -d. hello.helloimpl % jar cvf hello.jar hello/*.class 참고 1) rmic 는 stub 과 skel 을생성하는컴파일러이다.
<15> <Network Programming> 12.2 자바 RMI 예제 5. rmiregistry 를등록한다. % unsetenv CLASSPATH % rmiregistry & [1] 7382 6. 보안설정파일을생성한다. 예제 : java.policy 1 grant{ 2 permission java.net.socketpermission "*:1024-65535", 3 "connect,accept"; 4 permission java.net.socketpermission "*:80", "connect"; 5 }; 7. rmi 서버를가동시킨다. % java -Djava.security.policy=java.policy hello.helloimpl Hello Server ready
<16> <Network Programming> 2. 자바 RMI 예제 (6) 7. 클라이언트프로그램을실행시킨다. % java -Djava.security.policy=java.policy hello.helloclient HelloClient: Hello World RMI 클라이언트를애플릿으로작성한예제 예제 : HelloApplet.java 1 package hello; 2 3 import java.awt.*; 4 import java.applet.*; 5 import java.rmi.*; 6 7 public class HelloApplet extends Applet { 8 String message = ""; 9 10 public void init() {
<17> <Network Programming> 2. 자바 RMI 예제 (7) 11 try { 12 Hello obj = (Hello)Naming.lookup("//"+getCodeBase(). gethost() + "/hello"); 13 message = obj.sayhello(); 14 } catch(exception e) { 15 System.out.println("HelloApplet exception: " + e.getmessage()); 16 } 17 } 18 19 public void paint(graphics g) { 20 g.drawstring(message, 25, 50); 21 } 22 }
<18> <Network Programming> 2. 자바 RMI 예제 (8) 예제 : Hello.html 1 <html><title>hello World</title> 2 <applet code=hello.helloapplet archive=hello.jar width=400 height=400> 3 </applet> 4 </html> 컴파일하기 % javac -d. HelloApplet.java % jar cvf hello.jar hello/*.class 결과 % appletviewer Hello.html
<19> <Network Programming> 실습 : 원격계산기 - 서버측 서버측 1. Calfor.java : interface 함수정의 2. CalforImpl,java : 서버내에해당계산기함수정의 3. rmic 를이용하여 Skel.class 와 sub.class 생성 % rmic CalforImpl 4. rmiregistry 명령어를통한등록 % unsetenv CLASSPATH % rmiregistry & 5. rmi 서버를가동시킨다. %java -Djava.security.policy=java.policy CalforImpl Server ready
<20> <Network Programming> 실습 : 원격계산기 - 클라이언트측 클라이언트측 1. CalforImpl 원격객체를이용하는클라이언트프로그램 ( 클라이언트 ) 을작성한다. 2. 서버가등록되어실행이된후에클라이언트를실행시킨다. %java -Djava.security.policy=java.policy CalforClient.