本站首页    管理页面    写新日志    退出




行百里者半九十

 

«August 2025»
12
3456789
10111213141516
17181920212223
24252627282930
31

 

我的分类(专题)


日志更新

最新评论

留言板

链接

Blog信息
blog名称:行百里者半九十
日志总数:38
评论数量:21
留言数量:0
访问次数:266175
建立时间:2007年8月25日




JAVA RMI 学习
原创空间,  网上资源,  心得体会,  所见所闻,  软件技术,  职业生涯,  数码玩家,  其他

行百里者半九十 发表于 2008/9/17 20:42:57

    由于工作途中遇到了RMI(Remote Method Invocation 远程方法调用),它是一个分布式对象系统,它使你能够轻松地开发出分布式Java应用程序。在RMI中开发分布式应用程序比用套接字开发要简单,因为不需要做设计协议这种很容易出错的工作。在RMI中,开发者会有一种错觉,似乎是从本地类文件调用的本地方法,其实参数传送给了远程目标,目标解释参数后再把结果发回给调用方。 (以上系引用为主   源:http://tech.ccidnet.com/art/3539/20080526/1457809_1.html)   在学习RMI的过程中,有一个非常明显的感觉,那就是分布式的应用采用RMI来开发应该很快!首先,RMI通过定义接口和接口实现,使得客户端调用者和服务提供者分离,这样只要不改变接口定义,客户端就不用修改,而服务端则可以用自己的方式来修改或升级。   下面来简单介绍一下RMI应用的组成,并给出个人根据网上相关资源所写的一个简单例子。通常一个RMI应用应该分为:1、服务提供者和服务享受者协商确定的接口;2、接口在服务提供方的实现;3、服务提供程序;4、客户端调用程序。下面的源代码是我在JDK1.5下调试通过的,服务端程序在被调用时,会在服务端打印信息以显示正在提供服务,而客户端也会提示接收服务的相关信息,详细过程不再赘述,看看代码就一目了然了! 1、服务提供者和服务享受者协商确定的接口: /** * Created On 2008-9-17 By Ivan */package net.vicp.fst.rmi.operate; import java.rmi.Remote;import java.rmi.RemoteException; /** * @author Ivan 此接口用于定义本地和远程服务器上程序的公共接口 */public interface IOperateUtil extends Remote { /**  * 读取服务器上指定文件的内容返回  *   * @param absFileName  *            文件在服务器上的绝对路径(含文件名称)  * @return 文件内容  * @throws RemoteException  */ public String readFileContent(String absFileName) throws RemoteException;  /**  * 在服务器上执行命令,将命令执行的结果返回  *   * @param cmd  *            具体命令  * @return 命令执行结果  * @throws RemoteException  */ public String execCommand(String cmd) throws RemoteException;} 2、接口在服务提供方的实现: /** * Created On 2008-9-17 By Ivan */package net.vicp.fst.rmi.operate.impl; import java.rmi.RemoteException; import net.vicp.fst.rmi.operate.IOperateUtil; /** * @author Ivan 此类是IOperateUtil接口的实现 */public class OperateUtilImpl implements IOperateUtil {  /**  * 读取服务器上指定文件的内容返回  *   * @param absFileName  *            文件在服务器上的绝对路径(含文件名称)  * @return 文件内容  * @throws RemoteException  */ public String execCommand(String cmd) throws RemoteException {  System.out.println("远程客户端正在调用服务器执行命令:\"" + cmd + "\" !");  System.out.println("命令\"" + cmd + "\"执行完毕!");  return "命令:\"" + cmd + "\"执行的结果是:……"; }  /**  * 在服务器上执行命令,将命令执行的结果返回  *   * @param cmd  *            具体命令  * @return 命令执行结果  * @throws RemoteException  */ public String readFileContent(String absFileName) throws RemoteException {  System.out.println("远程客户端正在调用服务器读取文件:\"" + absFileName + "\"中的内容.");  System.out.println("文件\"" + absFileName + "\"的内容被读取完毕!");  return "文件\"" + absFileName + "\"中的内容是:……"; }} 3、服务提供程序: /** * Created On 2008-9-17 By Ivan */package net.vicp.fst.rmi.server; import java.rmi.Naming;import java.rmi.RMISecurityManager;import java.rmi.RemoteException;import java.rmi.registry.LocateRegistry;import java.rmi.server.UnicastRemoteObject;import net.vicp.fst.rmi.operate.IOperateUtil;import net.vicp.fst.rmi.operate.impl.OperateUtilImpl;/** * @author Ivan * 此类用于启动RMI服务器 */public class FstRmiServer extends UnicastRemoteObject {  private static final long serialVersionUID = 6158084897536450551L;  private IOperateUtil iou = null;  protected FstRmiServer() throws RemoteException {  super();  System.out.println("启动本地RMI服务器..."); }  /**  * 初始化RMI对象,并将RMI对象绑定到名称  */ public void startRMI(){  if(System.getSecurityManager()!=null){   System.setSecurityManager(new RMISecurityManager());  }  try {   iou = new OperateUtilImpl();   // 将该对象实例与名称FstRmiUtil绑定   LocateRegistry.createRegistry(1385);   Naming.bind("rmi://localhost:1385/FstRmiUtil", iou);   System.out.println("RMI服务启动成功!");  } catch (Exception e) {   System.err.println("RMI服务启动失败!详细信息如下:");   e.printStackTrace();  }  }  /**  * @param args  */ public static void main(String[] args) {  try{   FstRmiServer server = new FstRmiServer();   server.startRMI();  }catch(Exception e){   e.printStackTrace();  } }} 4、客户端调用程序: /** * Created On 2008-9-17 By Ivan */package net.vicp.fst.rmi.client;import java.net.MalformedURLException;import java.rmi.Naming;import java.rmi.NotBoundException;import java.rmi.RemoteException;import net.vicp.fst.rmi.operate.IOperateUtil;/** * @author Ivan 此类用于调用RMI服务器上服务 */public class FstRmiClient { public void invokeRMI(String IpAddress, String PortNumber, String ServiceName) {  try {   System.out.println("开始调用RMI服务...");   IOperateUtil iou = (IOperateUtil)Naming.lookup("rmi://" + IpAddress + ":" + PortNumber + "/"     + ServiceName);   //调用远程服务   String fileContent = iou.readFileContent("D:\\ftpRoot\\test.txt");   System.out.println(fileContent);      String cmdOut = iou.execCommand("type D:\\ftpRoot\\test.txt");   System.out.println(cmdOut);   System.out.println("调用RMI服务完毕!");  } catch (NotBoundException ne) {   System.err.println("调用RMI服务发生 NotBoundException 异常,详细信息如下:");   ne.printStackTrace();  } catch (MalformedURLException mue) {   System.err.println("调用RMI服务发生 MalformedURLException 异常,详细信息如下:");   mue.printStackTrace();  } catch (RemoteException re) {   System.err.println("调用RMI服务发生 RemoteException 异常,详细信息如下:");   re.printStackTrace();  } }  /**  * @param args 调用RMI服务的参数,详细入下<br>  * <ul>  *  args[0]:RMI服务器IP地址 <br>  *  args[1]:RMI服务端口 <br>  *  args[2]:RMI服务名称 <br>  * </ul>  */ public static void main(String[] args) {  FstRmiClient client = new FstRmiClient();  if(args.length != 3){   client.invokeRMI("192.168.1.77", "1385", "FstRmiUtil");  }else{   client.invokeRMI(args[0], args[1], args[2]);  } }}   将以上程序编译,然后分别打包成jar,客户端只需要知道接口的定义和客户端本身的调用程序,而服务器端则不需要知道客户端是怎么调用,但必须知道提供服务的实现。因此,打包的时候将1 2 3打包为服务器短运行的程序,将1 4打包成为客户端运行的程序即可!   测试的时候需要在客户端指定服务方的IP,端口以及服务绑定名称,具体的测试信息不再给出!


阅读全文(2253) | 回复(0) | 编辑 | 精华
 



发表评论:
昵称:
密码:
主页:
标题:
验证码:  (不区分大小写,请仔细填写,输错需重写评论内容!)



站点首页 | 联系我们 | 博客注册 | 博客登陆

Sponsored By W3CHINA
W3CHINA Blog 0.8 Processed in 0.031 second(s), page refreshed 144758623 times.
《全国人大常委会关于维护互联网安全的决定》  《计算机信息网络国际联网安全保护管理办法》
苏ICP备05006046号