RMI之所以使用的范围受限制主要有两方面原因,其一:必须要是java,平台的异构性受到限制;其二:穿越防火墙不方便。这里主要谈谈RMI如何通过固定分配端口来穿越防火墙。 RMI穿越防火墙不方便主要是因为除了RMI服务注册的端口(默认1099)外,与RMI的通讯还需要另外的端口来传送数据,而另外的端口是随机分配的,所以要想RMI的客户能通过防火墙来与RMI服务通讯,则需要能让随机分配的端口固定下来,具体做法如下:
1、增加一个文件SMRMISocket.java
import java.rmi.server.*;
import java.io.*;
import java.net.*;
public class SMRMISocket extends RMISocketFactory {
public Socket createSocket(String host, int port) throws IOException{
return new Socket(host,port);
}
public ServerSocket createServerSocket(int port) throws IOException {
if (port == 0)
port = 10990; //不指定就随机分配了
return new ServerSocket(port);
}
}
2、在实例化UnicastRemoteObject的子类前加入一下代码:
[java] view plaincopyprint?
try {
RMISocketFactory.setSocketFactory(new SMRMISocket());
} catch (Exception ex) {
}
这样的话RMI分配的端口就被固定了,防火墙只需要打开1099和10990端口即可。
---------------------------------------------------------------------------------------------------------------------------------
在用RMI做服务监控的时候碰到两个问题:
1. InetAddress.getLocalHost().getHostAddress(); 报错UnknowHost
linux /etc/hosts 加主机名以及映射
hostname hostname -i 能正确获取到就ok
----------------------------------------------------------------------------------------------------------------------------------
2. 先记录问题
1) 服务端重启客户端报错的问题
http://forum.springsource.org/showthread.php?t=61575
at monitor.SendHeartBeatThread.run(SendHeartBeatThread.java:32)
Caused by: java.rmi.NoSuchObjectException: no such object in table
at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:275)
at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:252)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:161)
at org.springframework.remoting.rmi.RmiInvocationWrapper_Stub.invoke(Unknown Source)
at org.springframework.remoting.rmi.RmiClientInterceptor.doInvoke(RmiClientInterceptor.java:397)
at org.springframework.remoting.rmi.RmiClientInterceptor.doInvoke(RmiClientInterceptor.java:343)
... 5 more
<bean id="beanId" class="org.springframework.remoting.rmi.RmiProxyFa ctoryBean">
<property name="serviceUrl" value="rmi://127.0.0.1:6666/appName"/>
<property name="serviceInterface" value="test.HelloI"/>
<!--property name="cacheStub" value="false"/-->
<property name="lookupStubOnStartup" value="false"/>
<property name="refreshStubOnConnectFailure" value="true"/>
</bean>
因为RMI stub被连接到特定的端点,不仅仅是为每个调用打开一个给定的目标地址的连接,所以如果重新启动RMI端点主机的服务器,那么就需要重新注册这些stub,并且客户端需要再次查询它们。
class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
<property name="serviceUrl">
<value>${showcasewiz.report.serviceurl}</value>
</property>
<property name="serviceInterface">
<value>com.meetexpo.showcase.backend.service.ReportService</value>
</property>
</bean>
class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
<property name="serviceUrl">
<value>${showcasewiz.report.serviceurl}</value>
</property>
<property name="serviceInterface">
<value>com.meetexpo.showcase.backend.service.ReportService</value>
</property>
</bean>
----------------------------------------------------------------------------------------------------------------------------------
2) 内网(局域网)间访问明明指定一个ip确变成另一个ip的情况)
Exception in thread "main" org.springframework.remoting.RemoteConnectFailureException: Cannot connect to remote service [rmi://218.206.203.3:9902/cmpayNotice]; nested exception is java.rmi.ConnectException: Connection refused to host: 10.97.164.26; nested exception is:
java.net.ConnectException: Connection timed out: connect
Caused by: java.rmi.ConnectException: Connection refused to host: 10.97.164.26; nested exception is:
java.net.ConnectException: Connection timed out: connect
以下from:http://dd2086.iteye.com/blog/362995
出错堆栈:
org.springframework.remoting.RemoteConnectFailureException: Cannot connect to remote service [rmi://192.168.2.61/Service]; nested exception is java.rmi.ConnectException: Connection refused to host: 192.168.7.11; nested exception is:
java.net.ConnectException: Connection timed out: connect
很奇怪,rmi访问的url是对的,但是后续的访问得到的IP却是双网卡中的另外一个无法访问的。
在本机做个简单试验:
System.out.println(UnicastRemoteObject.exportObject(new Remote(){},0));
输出:
Proxy[Remote,RemoteObjectInvocationHandler[UnicastRef [liveRef: [endpoint:[192.168.2.3:2339](local),objID:[0]]]]]
说明对象在没有注册出去的时候其IP就已经决定,绑定出去以后客户端就按照这个IP按图索骥。Server端有两个网卡,乱找一个就Over了。
这种方式对分布式对象注册很有用,但是碰到多IP的情况下就比较弱智了。sun的faq上给出一个简单答案:
http://java.sun.com/j2se/1.5.0/docs/guide/rmi/faq.html#netmultihomed
一句话:
System.setProperty("java.rmi.server.hostname","192.168.2.3");//建议从配置文件加载。
或
java -Djava.rmi.server.hostname=xxx -jar xxx.jar
http://yangwencan2002.iteye.com/blog/284249
http://hi.baidu.com/wolf55/item/1676aa0b41184417cd34ea52
相关推荐
rmi技术客户端调用服务器的函数解决问题 刚刚开始准备这个rmi作业的时候,我都有点无从下手。于是我先开始一起找资料,看书,经过不断的尝试编码,以及总结错误,为后期的工作奠定了基础。 在基础知识基本搞定的...
本项目使用socket直接发送数据包来攻击rmi,通过反序列化攻击rmi,双击直接运行,对1099端口的rmi服务直接进行漏洞检测。
java rmi 接口,使用WEB工程外的类访问WEB工程中的类,客户端的类访问远程服务端的类
java的Rmi组件,在服务端部署RmiServer.jar 以: java -jar RmiServer.jar 1199(端口号) 启动 <br>在客户端部署RmiClient.jar 直接调用其API即可完成对服务端后台程序的远程调用
// 数据端口,0表示端口由RMI服务器动态生成. private Remote stub; public RMIServer() { } /* * 使用默认端口,默认服务器名称,服务路径构造函数 use the default port,server name and the url */ public...
串行RMI 该程序将创建一个RMI服务,该服务可让您与串行端口进行通信。 RXTX库( )用作串行端口的连接器。 到现在为止,RMI服务实现了以下功能: String read() void write(String str) void writeLine(String str) ...
RMI-IIOP Java 源码实例,附有BAT批处理命令,Java EJB初学者可参考学习,EJB的例子。
简单实现了Java RMI实例,需手动更改IP和端口~
可以单机模拟多台电脑的环境。当然也可以在Eclipse中配置运行时程序的参数来运行程序(运行时参数主要负责传递端口号,服务器地址等)。
Java开发基于rmi的数据库中间件设计源码,并利用中间件建立一个数据库应(Java web项目),...绑定Rmi服务端口和主机(如果Rmi服务放在远程主机需要注意避开防火墙,并绑定主机,更有甚者需要指定另外一个通信端口)
PERFECTTIME.JAVA:向RMI注册服务,以便客户端查找,创建提供注册服务的本地对象,参数为端口号,也可以在Dos窗口下,执行start rmiregistry port启动此服务,注册把PerfectTime注册到机器192.8.200.27,端口2005,名为...
该项目是maven工程,由三个子模块,一个定义api和model实体,一个是远程服务(provider),...需要先build api, 然后再运行远程服务,最后运行调用方,在打包完成后,两者可以运行在不同服务器上,注意:需要修改ip和端口
activeMQ开启jmx固定rmi端口,穿透防火墙,用了一天的时间,踩了无数的坑,拿出来共享.
问题描述 今天一来公司,在IntelliJ IDEA 中启动Tomcat服务器时就出现了如下图所示的错误: 错误: 代理抛出异常错误: java.rmi.server.ExportException: Port already in use: 1099; nested exception is: java...
RMIDeserialize RMI反序列化学习环境,细节请参考博客、 java -cp RMIDeserialize.jar com.lala.ServerAndRegister :起一个包含CC链...本地JRMP服务端口>:攻击目标8u231版本以下的RMI服务。 其他功能可以从源码运行。
java rmi demo2 N个客户端,N个P2P节点,一个服务端,客户端连接P2P节点,服务端保存当前所有在线的客户端的IP和端口,客户端相当于我们的电脑。用户上传文件,都从客户端传到P2P节点中,然后每个P2P节点互相传输,...
基于RMI的服务器作者: Divya Nairy(5589575... 如果未提供端口,则使用默认的RMI端口1099。 java BankServerImpl 运行BankClient java BankClient <serverHostname> <severPortnumber> <threadCount> <iterationCo
通常为端口1099):远程对象注册表服务(rmiregistry) IIOP要求使用JRE 1.8。由于在以后的运行时中已弃用。 RMI SSL 多种操作模式 单词表模式:使用签名的单词表测试远程方法(请参阅随附的list / prototypes.txt...
1 slave机器的自定义端口号配置; 2 负载机(Slave)找不到参数文; 3 无数据,依赖文件报错的问题; 4 Server failed to start: java.rmi.server.ExportException: Listen failed on port…找不到指定文件; 5 ...
编写一个RMI的步骤 定义一个远程接口,此接口需要继承java.rmi.Remote 开发远程接口的实现类 创建一个server并把远程对象注册到端口 创建一个client查找远程对象,调用远程方法 实例 定义一个远程接口 public ...