RMI网络编程开发

注意该标题是 “进程”间通信,而并非“线程“之间的通信。

线程之间的通信是多线程的讨论范畴。这里我们是要讨论分布式的独立的JAVA程序之间是怎么通信的。当然,大家都会先想到SOCKET。对的,SOCKET在网络编程中是不可以被忽略的。socket是两台主机之间的一个连接,而JAVA中的SOCKET类为不同主机之间的连接提供了功能封装。

所以,SOCKET是进程间通信的一种常用方法。

让我们变得更原始一点,如果同一台主机不同程序之间是怎么交换数据的呢?

嗯,邮递员送信的网络知识,让我们很容易想到,把数据放到一个共享的地方就行。

A程序把数据存到硬盘的某个文件txt,然后B程序在去打开这个txt读取内容。这样子是不是很理想呢?

所以,存取文件,不失为一个通信的巧手段。

嗯,既然我们可以共享磁盘,那我们也可以共享内存,JMS的 queue 应该也可以实现通信的目的,

还有管道等概念。

讲了那么多,其实想引出来的,无非是RMI,RMI并不是最本质的东西。SOCKET是它的基础。

RMI是sun开发,遵循JRMP协议,因为他被发布在jre中,所有很多人只把它当作很普通的api来使用,所以它里面做了什么,很多人都不清楚. 

RMI到底是什么?

  • RMI是一套足够优秀的socket框架.
  • RMI是相对比较简单命名服务
  • RMI是aop的经典实用例子
  • 相关辅助功能,比如本地GC

总之,RMI也是一个重要的通信手段。


这里讲述的是基于JDK1.5的RMI程序搭建,更简单的说是一个 HelloWorld RMI。

1. 这里是基于JDK1.5的,节省了繁琐的手工编译(生成桩和骨架)。不像1.4之前的RMI。

2. 这里是把客户端和服务器端的两个程序,分布在两个独立的程序里面,而不是同一个package下面。是真正的分布式。

3. 这里不过多阐述原理,这只是一个Hello World!!

好,以下是步骤:

1. 在Eclipse里面创建一个server 端的project。然后,创建一个接口,这个接口是你要向client端开放的方法定义。它叫做:UserManagerInterface,而且必须继承Remote接口。

 
 
  1. package dataserver.rmi.stub; 
  2.  
  3. import java.rmi.Remote; 
  4. import java.rmi.RemoteException; 
  5.  
  6. import dataserver.rmi.bean.Account; 
  7.  
  8. public interface UserManagerInterface extends Remote{ 
  9.     public String getUserName() throws RemoteException; 
  10.     public Account getAdminAccount() throws RemoteException; 

2. 为了证明RMI中,“面向对象”或者是“无缝传递JAVA Object”是何等简单,我们需要定义一个Account类,该类是一个Bean,必须实现implements Serializable序列化接口。这是一个可以在client和server传输的可序列化对象。

 
 
  1. package dataserver.rmi.bean; 
  2.  
  3. import java.io.Serializable; 
  4.  
  5. public class Account implements Serializable,Cloneable{ 
  6.  
  7.     /** 
  8.      *  
  9.      */ 
  10.     private static final long serialVersionUID = -1858518369668584532L; 
  11.     private String username; 
  12.     private String password; 
  13.      
  14.     public String getUsername() { 
  15.         return username; 
  16.     } 
  17.     public void setUsername(String username) { 
  18.         this.username = username; 
  19.     } 
  20.     public String getPassword() { 
  21.         return password; 
  22.     } 
  23.     public void setPassword(String password) { 
  24.         this.password = password; 
  25.     } 
  26.      

3. 此时,需要实现你已经开放的接口:

 
 
  1. package dataserver.rmi; 
  2.  
  3. import java.rmi.RemoteException; 
  4.  
  5. import dataserver.rmi.bean.Account; 
  6. import dataserver.rmi.stub.UserManagerInterface; 
  7.  
  8. public class UserManagerImpl implements UserManagerInterface { 
  9.  
  10.     public UserManagerImpl() throws RemoteException { 
  11.         //super(); 
  12.         // TODO Auto-generated constructor stub 
  13.         //UnicastRemoteObject.exportObject(this); 
  14.     } 
  15.  
  16.     /** 
  17.      *  
  18.      */ 
  19.     private static final long serialVersionUID = -3111492742628447261L; 
  20.  
  21.     public String getUserName() throws RemoteException { 
  22.         // TODO Auto-generated method stub 
  23.         return "Tommy Lee"
  24.     } 
  25.  
  26.     public Account getAdminAccount() throws RemoteException { 
  27.         // TODO Auto-generated method stub 
  28.         Account account=new Account(); 
  29.         account.setUsername("admin"); 
  30.         account.setPassword("admin"); 
  31.         return account; 
  32.     } 
  33.  

4. 定义一个主程序入口,注册你已经实现的RMI接口,包括开放端口等。其实很简单:

把我们的接口名称,命名为“userManager”,方便client进行调用

 
 
  1. package dataserver.entry; 
  2.  
  3. import java.rmi.AlreadyBoundException; 
  4. import java.rmi.RemoteException; 
  5. import java.rmi.registry.LocateRegistry; 
  6. import java.rmi.registry.Registry; 
  7. import java.rmi.server.UnicastRemoteObject; 
  8.  
  9. import dataserver.rmi.UserManagerImpl; 
  10. import dataserver.rmi.stub.UserManagerInterface; 
  11.  
  12. public class Entry { 
  13.  
  14.     public static void main(String []args) throws AlreadyBoundException, RemoteException{ 
  15.      
  16.  
  17.             UserManagerImpl userManager=new UserManagerImpl(); 
  18.             UserManagerInterface userManagerI=(UserManagerInterface)UnicastRemoteObject.exportObject(userManager,0); 
  19.             // Bind the remote object's stub in the registry 
  20.             Registry registry = LocateRegistry.createRegistry(2001); 
  21.             registry.rebind("userManager", userManagerI); 
  22.             System.out.println("server is ready"); 
  23.     } 

 

5. Server端的代码已经全部写完,但是还要把bean类(Account)和接口类(UserMangerInterface)打包成jar,以便可以在下面导入进client端的项目中。

项目--》右键--》导出--》jar--》选择bean和interface--》命名为RmiServerInterface.jar--》finish

6.  开始创建client端的程序。新建一个project。创建完成后,把刚才jar包导入进client的项目中。

7.  导入我们的接口jar以后,可以开始编写一个client端的主程序,并调用server端的方法。

 
 
  1. package weiblog.rmi; 
  2. import java.rmi.NotBoundException; 
  3. import java.rmi.RemoteException; 
  4. import java.rmi.registry.LocateRegistry; 
  5. import java.rmi.registry.Registry; 
  6.  
  7. import dataserver.rmi.stub.UserManagerInterface; 
  8.  
  9. public class Entry2 { 
  10.  
  11.     public static void main(String []args){ 
  12.          
  13.         try { 
  14.             Registry registry = LocateRegistry.getRegistry("localhost",2001); 
  15.             UserManagerInterface userManager = (UserManagerInterface) registry.lookup("userManager"); 
  16.             System.out.println(""+userManager.getAdminAccount().getUsername() 
  17.                     +userManager.getAdminAccount().getPassword()); 
  18.         } catch (RemoteException e) { 
  19.             // TODO Auto-generated catch block 
  20.             e.printStackTrace(); 
  21.         } catch (NotBoundException e) { 
  22.             // TODO Auto-generated catch block 
  23.             e.printStackTrace(); 
  24.         } 
  25.          
  26.     } 

8. 启动server端的主程序,然后启动client端的主程序。

server控制台打印:server is ready

client控制台打印:adminadmin

大功告成!!


 

 

 

 

本文出自 “JAVAWeb开发” 博客,请务必保留此出处http://6221123.blog.51cto.com/6211123/1112619


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值