1 / 39

Advanced Network Programming

Advanced Network Programming. Ren Jiansi renjsv@cug.edu.cn. Java RMI 技术. (Remote Method Invocation ). RMI 基本原理 : RMI 能让一个 Java 程序调用网络中另外一台计算机的 Java 对象的方法,效果就像这个远程计算机上的对象方法在本地机上一样。 RMI 采用客户 / 服务器通信方式 RMI 应用的开发步骤 : 1. 创建 远程接口 远程接口必须继承 java.rmi.Remote 类。

jake
Download Presentation

Advanced Network Programming

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Advanced Network Programming Ren Jiansi renjsv@cug.edu.cn

  2. Java RMI技术 (Remote Method Invocation )

  3. RMI基本原理: RMI能让一个Java程序调用网络中另外一台计算机的Java对象的方法,效果就像这个远程计算机上的对象方法在本地机上一样。 RMI采用客户/服务器通信方式 RMI应用的开发步骤: 1.创建远程接口 远程接口必须继承java.rmi.Remote类。 接口中方法必须抛出java.rmi.RemoteException异常。 2.创建远程类 实现远程接口 远程类的命名是远程接口类名加上“Impl”(不是必须),例如,远程接口Upper类对应的远程接口实现类名为UpperImpl。

  4. 3.创建服务器程序 服务器程序的一大任务就是向rmiregistry注册表注册远程对象。 4.创建客户程序 运行RMI应用: • 启动注册表 start rmiregistry 默认监听1099端口,可使用命令 start rmiregistry 8000监听别的端口如8000 程序中服务器帮定对象和客户查找远程对象都要变更端口rmi://localhost:8000/… 2. 启动服务器程序 start java SimpleServer 3. 启动客户程序 java SimpleClient

  5. 例1:开发一个远程方法upperCase(String str),它把客户(调用者)提供的字符串传送给服务者,服务者把它全部转变成大写字符串后返回给客户。 1.创建远程接口 Upper.java import java.rmi.*; public interface Upper extends Remote { String upperCase(String s) throws RemoteException;}

  6. 2.创建远程类 UpperImpl.java import java.rmi.*; import java.rmi.server.UnicastRemoteObject; public class UpperImpl extends UnicastRemoteObject implements Upper { public UpperImpl() throws RemoteException { } public String upperCase(String s) throws RemoteException { return s.toUpperCase(); //字符串类的方法 } }

  7. 3.创建服务器程序 UpperServer.java import java.rmi.*; import javax.naming.*; public class UpperServer{ public static void main( String args[] ){ try { Upper service = new UpperImpl(); Context namingContext=new InitialContext(); namingContext.rebind( "rmi:Upper1", service); System.out.println("服务器注册了一个Upper对象" ); } catch (Exception e) { e.printStackTrace(); } }}

  8. 4.创建客户程序UpperClient.java import java.rmi.*; import javax.naming.*; public class UpperClient { public static void main(String[] arg) { String url="rmi://localhost/"; try { Context namingContext=new InitialContext(); Upper service=(Upper)namingContext.lookup(url+"Upper1"); //利用参数“abc”远程调用方法upperCase() System.out.println(service.upperCase("abc")); } catch (Exception e) {e.printStackTrace();} }}

  9. 例2: 1.创建远程接口 HelloService.java import java.util.Date; import java.rmi.*; public interface HelloService extends Remote{ public String echo(String msg) throws RemoteException; public Date getTime() throws RemoteException; }

  10. 2.创建远程类 HelloServiceImpl.java import java.util.Date; import java.rmi.*; import java.rmi.server.UnicastRemoteObject; public class HelloServiceImpl extends UnicastRemoteObject implements HelloService{ private String name; public HelloServiceImpl(String name)throws RemoteException{ this.name=name; }

  11. public String echo(String msg)throws RemoteException{ System.out.println(name+":调用echo()方法"); return "echo:"+msg +" from "+name; } public Date getTime()throws RemoteException{ System.out.println(name+":调用getTime()方法"); return new Date(); } }

  12. 3.创建服务器程序SimpleServer.java import java.rmi.*; import javax.naming.*; public class SimpleServer{ public static void main( String args[] ){ try{ HelloService service1 = new HelloServiceImpl("service1"); HelloService service2 = new HelloServiceImpl("service2");

  13. Context namingContext=new InitialContext(); namingContext.rebind( "rmi:HelloService1", service1 ); namingContext.rebind( "rmi:HelloService2", service2 ); System.out.println( "服务器注册了两个HelloService对象" ); }catch(Exception e){ e.printStackTrace(); } } }

  14. 4.创建客户程序SimpleClient.java import java.rmi.*; import javax.naming.*; public class SimpleClient{ public static void main( String args[] ){ String url="rmi://localhost/"; try{ Context namingContext=new InitialContext(); HelloService service1=(HelloService)namingContext.lookup(url+"HelloService1"); HelloService

  15. service2=(HelloService)namingContext.lookup(url+"HelloService2"); System.out.println(service1.echo("hello")); System.out.println(service1.getTime()); System.out.println(service2.echo("hello")); System.out.println(service2.getTime()); }catch( Exception e){ e.printStackTrace(); } } }

  16. SimpleServer端的打印结果如下:

  17. SimpleClient端的打印结果如下:

  18. CORBA CORBA(Common Object Request Broker Architecture,公共对象请求代理结构) 是OMG (Object Management Group,对象管理组织)制定的一个基于开放标准的分布式计算解决方案,它的主要目的是支持用户在计算机硬件、操作系统、程序设计语言和网络通信协议异构的情况下方便地开发健壮的、可伸缩的、面向对象的分布式应用。

  19. CORBA和Java都采用面向对象技术,因此,可以很容易地用Java语言开发CORBA应用,或将Java应用以及JavaBean对象集成到CORBA应用环境中;CORBA和Java都适用于开发分布式应用,所不同的是:CORBA偏重于通用的分布式应用开发,而Java注重于WWW环境中的分布式应用开发。 CORBA 采用客户/服务器模式。 CORBA独立于任何编程语言,独立于任何操作系统平台。在Linux中用Java编写的CORBA对象可以与Windows操作系统中用C++编写的CORBA对象通信。 IDL语言是一种接口定义语言。IDL语言不同于所有已有的程序设计语言,它是一种描述性语言,也就是说,用它描述得到的接口是不能直接被编译执行。 IDL独立于任何其他编程语言。

  20. 创建CORBA程序的步骤: 1.创建IDL接口 2.创建IDL接口的实现类 3.创建服务器程序 创建并注册CORBA对象 orbd.exe是 JDK提供的一个CORBA的命名服务器程序 4.创建客户程序 运行CORBA程序: 1. 编译IDL接口 idlj -fall HelloService.idl 2. 启动命名服务器程序 start orbd -ORBInitialPort 1050 1050为命名服务器监听的端口

  21. 3. 启动服务器程序 start java hello.HelloServer -ORBInitialPort 1050 -ORBInitialHost localhost 4. 运行客户程序 java hello.HelloClient -ORBInitialPort 1050 -ORBInitialHost localhost 例1: 利用Java与CORBA技术开发一个远程方法upperCase(string str),它把客户(调用者)传送来的字符串全部转变成大写字符串后返回给客户。

  22. 1.创建IDL接口 UpperModule.idl module UpperModule { interface Upper { string upperCase(in string str); }; };

  23. 2.创建IDL接口的实现类UpperImpl.java package UpperModule; public class UpperImpl extends UpperPOA { public UpperImpl() { } public String upperCase (String str) { //返回结果: return str.toUpperCase(); } }

  24. 3.创建服务器程序UpperServer.java package UpperModule; import java.io.*; import org.omg.CORBA.*; import org.omg.CosNaming.*; import org.omg.PortableServer.*; import org.omg.PortableServer.POA; import org.omg.CosNaming.NamingContextPackage.*; public class UpperServer { public static void main(String args[]) { try{

  25. // 初始化ORB对象 ORB orb = ORB.init(args, null); // 建立接口实现类UpperImpl对象,并与ORB连接 UpperImpl upperImpl= new UpperImpl(); //取得RootPOA引用,并激活POAManager POA rootpoa = POAHelper.narrow( orb.resolve_initial_references("RootPOA")); rootpoa.the_POAManager().activate(); //取得对象引用 org.omg.CORBA.Object ref = rootpoa.servant_to_reference(upperImpl);

  26. Upper href = UpperHelper.narrow(ref); //获得命名服务的Context org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService"); NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef); //绑定对象引用 String name = "Upper"; NameComponent path[] = ncRef.to_name( name ); ncRef.rebind(path, href);

  27. System.out.println("UpperServer ready ...."); // 等待客户调用 orb.run(); } catch(Exception e) { System.err.println("ERROR: " + e); e.printStackTrace(System.out); } } }

  28. 4.创建客户程序UpperClient.java package UpperModule; import java.io.*; import org.omg.CORBA.*; import org.omg.CosNaming.*; import org.omg.CosNaming.NamingContextPackage.*; public class UpperClient { public static void main(String args[]) { try { String str;

  29. // 初始化ORB对象 ORB orb = ORB.init(args, null); //使用命名服务获得NamingContext。NameService 是所有ORB命名的总称。 org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService"); //用NamingContextExt代替NamingContext NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef); //用名称解析对象引用 String name = "Upper";

  30. Upper upper= UpperHelper.narrow(ncRef.resolve_str(name)); //调用远程方法upperCase() str= upper.upperCase("abc"); System.out.println(str); } catch(Exception e) {System.out.println("ERROR : " + e); e.printStackTrace(System.out); } } }

  31. 例2: 1.创建IDL接口 HelloService.idl module hello{ interface HelloService{ string sayHello(); }; };

  32. 2.创建IDL接口的实现类HelloServiceImpl.java package hello; import org.omg.CosNaming.*; import org.omg.CosNaming.NamingContextPackage.*; import org.omg.CORBA.*; import org.omg.PortableServer.*; import org.omg.PortableServer.POA; import java.util.Properties; public class HelloServiceImpl extends HelloServicePOA { public String sayHello() { return "\nHello world !!\n"; }}

  33. 3.创建服务器程序HelloServer.java package hello; import org.omg.CosNaming.*; import org.omg.CosNaming.NamingContextPackage.*; import org.omg.CORBA.*; import org.omg.PortableServer.*; import org.omg.PortableServer.POA; import java.util.Properties; public class HelloServer { public static void main(String args[]) { try{

  34. //创建和初始化ORB ORB orb = ORB.init(args, null); //获得根POA的引用,并且激活POAManager POA rootpoa =POAHelper.narrow(orb.resolve_initial_references("RootPOA")); rootpoa.the_POAManager().activate(); //创建一个HelloServiceImpl对象,并且把它与ORB关联 HelloServiceImpl helloServiceImpl = new HelloServiceImpl();

  35. //获得HelloServiceImpl对象的CORBA类型的对象引用 org.omg.CORBA.Object ref = rootpoa.servant_to_reference(helloServiceImpl); HelloService href = HelloServiceHelper.narrow(ref); //获得命名服务的Context org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService"); NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef);

  36. //把HelloService对象与“HelloService”名字绑定 String name = "HelloService"; NameComponent path[] = ncRef.to_name( name ); ncRef.rebind(path, href); System.out.println("HelloServer ready and waiting ..."); //等待客户端访问HelloService对象 orb.run(); }catch (Exception e) { System.err.println("ERROR: " + e); e.printStackTrace(System.out); } }}

  37. 4.创建客户程序HelloClient.java package hello; import org.omg.CosNaming.*; import org.omg.CosNaming.NamingContextPackage.*; import org.omg.CORBA.*; public class HelloClient{ static HelloService helloServiceImpl; public static void main(String args[]){ try{ //创建和初始化ORB ORB orb = ORB.init(args, null);

  38. //获得命名服务的Context org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService"); NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef); //获得名为“HelloService”的HelloService对象的远程引用 String name = "HelloService"; helloServiceImpl = HelloServiceHelper.narrow(ncRef.resolve_str(name));

  39. //调用HelloService对象的远程方法 System.out.println(helloServiceImpl.sayHello()); }catch (Exception e) { System.out.println("ERROR : " + e) ; e.printStackTrace(System.out); } } }

More Related