javasec(六)RMI
这篇文章介绍java-RMI远程方法调用机制。
RMI全称是Remote Method Invocation,远程⽅法调⽤。是让某个Java虚拟机上的对象调⽤另⼀个Java虚拟机中对象上的⽅法,只不过RMI是Java独有的⼀种RPC方法。看这篇之前可以先去看看RPC:https://www.bilibili.com/video/BV1zE41147Zq?from=search&seid=13740626242455157002
RMI流程
RMI远程⽅法调⽤的流程:

先介绍各个部分的功能作用:
- Stub:客户端调用一个被称为 Stub (存根)的客户端代理对象。该代理对象负责对客户端隐藏网络通讯的细节。Stub 写着如何通过网络套接字(Socket)发送调用,包括如何将调用参数转换为适当的形式以便传输等。简单理解就是封装了一层网络传输的细节,直接传入参数调用就行。
- Skeleton:在服务端中该代理对象负责对分布式对象隐藏网络通讯的细节。Skeleton 知道如何从网络套接字(Socket)中接受调用,包括如何将调用参数从网络传输形式转换为 Java 形式等。
- Registry:注册中心,服务端在注册中心注册服务时,需要提供一个key以及一个value,这个value是一个远程对象,Registry会对这个远程对象进行封装,使其转为一个远程代理对象,它本身不会执行方法。在低版本的JDK中,Server与Registry是可以不在一台服务器上的,而在高版本的JDK中,Server与Registry只能在一台服务器上,否则无法注册成功。
- 注:
- Java对远程访问RMI Registry做了限制,只有来源地址是localhost的时候,才能调用rebind、bind、unbind等方法。
- 不过list和lookup方法可以远程调用。
- list方法可以列出目标上所有绑定的对象;lookup作用就是获得某个远程对象。
那么,只要目标服务器上存在一些危险方法,我们通过RMI就可以对其进行调用。
利用工具:https://github.com/NickstaDB/BaRMIe
建立RMI的流程如下:
- 通过分析需求定义远程接口(客户端和服务器端公用的),此接口必须扩展java.rmi.Remote,且远程方法必须声明抛出 java.rmi.RemoteException 异常,或者该异常的超类(Superclass)。
- 服务器端实现远程接口,为了不手动生成stub需要继承UnicastRemoteObject类,并调用其构造器;
- 服务器端注册服务并启动;
- 客户端查询服务并调用远程方法;
代码实现
分别建立三个项目:服务器端(RMIDemoServer)、客户端(RMIDemoClient)和远程接口(DemoRMI.RmoteInterface)

DemoRMI.RmoteInterface
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface HelloRMI extends Remote {
String sayHello(String name) throws RemoteException;
}
//继承了 java.rmi.Remote 的接⼝,其中定义我们要远程调⽤的函数,⽐如这⾥的 sayHello(String name)
RMIDemoServer
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
@SuppressWarnings("serial")
public class RMIHelloImpl extends UnicastRemoteObject implements HelloRMI {
protected RMIHelloImpl() throws RemoteException {
super();
}
public String sayHello(String name) {
return "Hello,"+name;
}
}
//实现了接⼝的类 这里输出Hello 传入的值
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
public class SerApp
{
public static void main( String[] args ) throws RemoteException, MalformedURLException
{
HelloRMI hello= (HelloRMI) new RMIHelloImpl();
LocateRegistry.createRegistry(1099);
Naming.rebind("rmi://127.0.0.1/hello", hello);
System.out.println("Server ok");
}
}
//创建Registry,并将实现类实例化后绑定到⼀个地址。这两部分就是我们所谓的Server
RMIDemoClient
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
public class ClientApp {
public static void main( String[] args ) throws MalformedURLException, RemoteException, NotBoundException
{
HelloRMI hello=(HelloRMI) Naming.lookup("rmi://127.0.0.1/hello");
System.out.println( hello.sayHello("Roderick RMI"));
}
}
//客户端就简单多了,使⽤ Naming.lookup 在Registry中寻找到名字是hello的对象,调用hello.sayHello
简单说一下这个流程:首先定义公共的接口HelloRMI,然后服务端创建实现类RMIHelloImpl,同时创建Registry并将实现类实例化后绑定到⼀个地址。这样RMI的Server就算完成了,再直接启动SerApp。客户端直接用Naming.lookup去访问Registry获取对象,然后像使用本地方法一样使用RMI来的方法即可方法。启动ClientApp可以看到完成了RMI整个调用过程。
借用p牛的解说:
“过程进行了了两次TCP握手,也就是我们实际建立了两次TCP连接。第⼀一次建立TCP连接是连接远端的1099端口,这也是我们在代码⾥里里看到的端口,⼆二者进行沟通后,我向远端发送了一个“Call”消息,远端回复了一个“ReturnData”消息,然后我新建了一个TCP连接,连到远端的33769端口。所以捋一捋这整个过程,首先客户端连接Registry,并在其中寻找Name是Hello的对象,这个对应数据流中的Call消息;然后Registry返回一个序列化的数据,这个就是找到的Name=hello的对象,这个对应数据流中的ReturnData消息;客户端反序列化该对象,发现该对象是一个远程对象,地址在x.x.x.x:端口,于是再与这个地址建⽴立TCP连接;在这个新的连接中,才执行真正远程方法调⽤用,也就是hello()。”
借用下图来说明这些元素间的关系:
RMI Registry就像一个网关,他自己是不不会执行远程方法的,但RMI Server可以在上⾯面注册一个Name到对象的绑定关系;RMI Client通过Name向RMI Registry查询,得到这个绑定关系,然后再连接RMIServer;最后,远程方法实际上在RMI Server上调用。
一个枚举和攻击 Java RMI(远程方法调用)服务的工具:https://github.com/NickstaDB/BaRMIe
javasec(六)RMI的更多相关文章
- Java学习笔记(十六)——Java RMI
[前面的话] 最近过的好舒服,每天过的感觉很充实,一些生活和工作的技巧注意了就会发现,其实生活也是可以过的如此的有滋有味,满足现在的状况,并且感觉很幸福. 学习java RMI的原因是最近在使用dub ...
- Docker入门教程(六)另外的15个Docker命令
Docker入门教程(六)另外的15个Docker命令 [编者的话]DockerOne组织翻译了Flux7的Docker入门教程,本文是系列入门教程的第六篇,继续介绍Docker命令.之前的第二篇文章 ...
- Spring的RMI远程调用 - (示例)
一.定义远程服务器上接口 public interface RMIService { public String getInfo(); } 二.实现远程服务器上接口 public class RMIS ...
- Java学习随笔——RMI
RMI(Remote Method Invocation)远程方法注入,用来实现远程方法调用,是实现分布式技术的一种方法.RMI提供了客户辅助对象和服务辅助对象,为客户辅助对象创建了和服务对象相同的方 ...
- SpringBoot里使用RMI进行远程方法调用
一.Java RMI定义 Java RMI:Java远程方法调用,即Java RMI(Java Remote Method Invocation)是Java编程语言里,一种用于实现远程过程调用的应用程 ...
- java rmi 入门实例
java rmi 入门实例 (2009-06-16 16:07:55) 转载▼ 标签: java rmi 杂谈 分类: java-基础 java rmi即java远程接口调用,实现了2台虚拟机之 ...
- 20155313 2016-2017-2 《Java程序设计》第六周学习总结
20155313 2016-2017-2 <Java程序设计>第六周学习总结 教材内容学习 第十章 输入/输出 10.1 InputStream与OutputStream 1.串流设计的概 ...
- Java学习---RMI 技术分析[Hessian]
一.什么是Hessian Hessian 是一个基于 binary-RPC 实现的远程通讯 library.使用二进制传输数据.Hessian通常通过Web应用来提供服务,通过接口暴露.Servlet ...
- [JAVA反序列化DEMO]利用RMI进行反序列化一键启动工具
功能: 命令行启动jar包,用户自定义启动RMI端口.默认内置Apache Commons Collections.只需一键启动即可测试java反序列化漏洞. 启动服务: [root@sevck_v3 ...
- 【面试 JVM】【第六篇】JVM调优
六部分内容: 一.内存模型 1.程序计数器,方法区,堆,栈,本地方法栈的作用,保存那些数据 可以画个大图出来,很清晰 jvm内存模型主要指运行时的数据区,包括5个部分. 栈也叫方法栈,是线程私有的,线 ...
随机推荐
- AD使用积累 - 板子上开孔的方法
有时候画板子时需要需要在板子上开一些槽孔,可以参考如下两种方法: 第一种方法:封闭曲线转换为槽孔. 1.在机械层画一个封闭图形或者画一根线: 2.选中这个图形或线,选择工具 - 转换 - 以选中的元素 ...
- 关于SSD硬盘
2月份,看到Netac的SSD硬盘便宜,入手一个720G的,把原来的三星250G换掉,有时感觉机器会卡,一直没注意,最近更新一个英睿达的MX系列500G放电脑里用,毕竟杂牌做主硬盘不放心.就把Neta ...
- 如何让charles无论怎么请求都返回一个结果
1. map Local 将匹配的url映射到本地文件.这个需要首先将url右键,save Response,将原有报文保存到本地,然后映射到该文件,修改该文件即可,直接自己写费事2. ...
- 自行封装JDBCUtils
自己封装JDBCUtils package com.javasm.util; import com.javasm.bean.Emp; import com.javasm.constants.JDBCC ...
- js指南
1.for /in: 与for/of相比,可迭代对象不同,in后面可以是任意对象.数组.字符串.集合和映射可迭代. object.keys() object.values() object.e ...
- 谈恋爱要做什么事?基于auto.js自动发早安给女朋友
谈恋爱要做什么事?除了用心之外,每天早安晚安必然是少不了的.但是每天都发免不了会忘, 为了避免遗忘,引起不必要的尴尬,我们可以做个自动化脚本来做这件事. 1 auto.js 是什么? Auto.JS是 ...
- idea中执行“npm/yarn”命令,提示'node/yarn' 不是内部或外部命令,也不是可运行的程序
问题:idea中执行"npm/yarn"命令,提示'node/yarn' 不是内部或外部命令,也不是可运行的程序.但是在本地打开cmd 是可以运行npm/yarn命令的 解决方法: ...
- Nginx + Keepalived 高可用集群部署
负载均衡技术对于一个网站尤其是大型网站的web服务器集群来说是至关重要的!做好负载均衡架构,可以实现故障转移和高可用环境,避免单点故障,保证网站健康持续运行.在使用 Nginx 做反向代理或者负载均衡 ...
- 统一返回对象Result
统一返回对象Result 项目中我们会将响应封装成json返回,一般我们会将所有接口的数据格式统一, 使前端(iOS Android, Web)对数据的操作更一致.轻松. 一般情况下,统一返回数据格式 ...
- Dubbo和Zookeeper(Springboot集成)
Dubbo和Zookeeper集成: 分布式理论: 分布式系统是由一组通过网络进行通信.为了完成共同的任务而协调工作的计算机节点组成的系统.分布式系统的出现是为了用廉价的.普通的机器完成单个计算机无法 ...