RMI远程调用时的内外网端口映射问题(RMI远程调用如何穿透防火墙)
2011-12-30 12:42
381 查看
转载自:http://www.juuluu.org/html/softDoc/2011/10/19/09/45/wtpnkjxlwt.html
以下是一个RMI项目的实施笔记:
环境:防火墙(XX卫士) 外网IP:x.x.x.135 port:8400/8500 内网IP: x.x.x.90 port:8400/8500
内外网IP及port互相映射. (外网IP是设定的防火墙上的,管理员进行映射配置)
1.RMI远程调用的服务注册到:内网的8400端口上 (不用创建stub/skeleton,不使用缺省的1099)
//LocateRegistry.createRegistry(rmiServerPort); //定义服务注册与查找服务端口 8400
2.RMI远程调用的数据通信端口绑定到:内网的8500端口上
// RMISocketFactory.setSocketFactory(new SMRMISocket()); //定义数据传输端口 8500
3.设定访问外网:x.x.x.135:8400时穿透防火墙访问内网:x.x.x.90:8400
//在sun.rmi.server.UnicastRef调用时的服务IP为:x.x.x.135,而不是x.x.x.90(客户的本地不存在RMI服务嘛)
//System.setProperty("java.rmi.server.hostname","x.x.x.135");
4.RMI调用穿透防火墙不是自动的,需要我们手工指定,就如3所指,如果不加设定,在互联网上就不能通过外网IP访问内网IP上绑定的RMI服务
5.通过本项目,明白了RMI可以不用rmic创建stub/skeleton的,也可以不用启动rmiRegistry而通过程序直接启动RMI服务,这样方便了代码的修改与项目的实施.
由于是项目代码,所以不打包上传代码了。简写如下:
///////RMI服务端代码
String hostIP = InetAddress.getLocalHost().getHostAddress();
int rmiServerPort = 8400; //数据传输服务为8400
String bindName = "licenseServer";
//下面这行代码不能少,否则当路由器x.x.x.135映射到的内网IP:x.x.x.90时,
//访问RMI服务时将导向本地的x.x.x.90,那么客户端就是访问本地x.x.x.90,
//这绝对错误.服务是在公网路由器(含公共IP)的后面,不在客户的本地
System.setProperty("java.rmi.server.hostname","x.x.x.135");
try {
RMISocketFactory.setSocketFactory(new SMRMISocket()); //定义数据传输端口 8500
LocateRegistry.createRegistry(rmiServerPort); //定义服务注册与查找服务端口 8400
}
catch (Exception ex) {
System.out.println("服务器端口绑定时发生错误:"+ex.getMessage());
ex.printStackTrace();
}
//创建license生成器的服务对象
MakeLicense licenseService = new MakeLicenseService();
//绑定一个服务对象到一个服务端口
//URL format (without the scheme component)
String bindUrl = "//"+hostIP+":"+ rmiServerPort +"/"+bindName;
Naming.rebind(bindUrl, licenseService);
System.out.println(bindUrl+" server is ready.");
////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 = 8500;
System.out.println("RMI服务器的注册与数据传输端口 ="+port);
return new ServerSocket(port);
}
}
////客户端代码:
private String remoteHost = "x.x.x.135"; //公网IP或局域网IP
private int rmiServerPort=8400; //查找服务端口 8400
private String bindName = "licenseServer"; //RMI服务名称
private int revCount = 0;
private MakeLicense remoteObject=null;
public LicenseRequestClient() {
try{
// if(System.getSecurityManager()==null){
// System.setSecurityManager(new RMISecurityManager());
// }
String bindUrl = "//"+remoteHost+":"+ rmiServerPort +"/"+bindName;
System.out.println("请求的远程服务URL="+bindUrl);
MakeLicense remoteObject = (MakeLicense) Naming.lookup(bindUrl);
this.remoteObject = remoteObject;
// System.out.print("远程remoteObject="+remoteObject);
}
catch (RemoteException re) {
System.out.println("RemoteException:" + re);
}
catch (NotBoundException nbe) {
System.out.println("NotBoundException:" + nbe);
}
catch (MalformedURLException mfe) {
System.out.println("MalformedURLException:" + mfe);
}
}
以下是一个RMI项目的实施笔记:
环境:防火墙(XX卫士) 外网IP:x.x.x.135 port:8400/8500 内网IP: x.x.x.90 port:8400/8500
内外网IP及port互相映射. (外网IP是设定的防火墙上的,管理员进行映射配置)
1.RMI远程调用的服务注册到:内网的8400端口上 (不用创建stub/skeleton,不使用缺省的1099)
//LocateRegistry.createRegistry(rmiServerPort); //定义服务注册与查找服务端口 8400
2.RMI远程调用的数据通信端口绑定到:内网的8500端口上
// RMISocketFactory.setSocketFactory(new SMRMISocket()); //定义数据传输端口 8500
3.设定访问外网:x.x.x.135:8400时穿透防火墙访问内网:x.x.x.90:8400
//在sun.rmi.server.UnicastRef调用时的服务IP为:x.x.x.135,而不是x.x.x.90(客户的本地不存在RMI服务嘛)
//System.setProperty("java.rmi.server.hostname","x.x.x.135");
4.RMI调用穿透防火墙不是自动的,需要我们手工指定,就如3所指,如果不加设定,在互联网上就不能通过外网IP访问内网IP上绑定的RMI服务
5.通过本项目,明白了RMI可以不用rmic创建stub/skeleton的,也可以不用启动rmiRegistry而通过程序直接启动RMI服务,这样方便了代码的修改与项目的实施.
由于是项目代码,所以不打包上传代码了。简写如下:
///////RMI服务端代码
String hostIP = InetAddress.getLocalHost().getHostAddress();
int rmiServerPort = 8400; //数据传输服务为8400
String bindName = "licenseServer";
//下面这行代码不能少,否则当路由器x.x.x.135映射到的内网IP:x.x.x.90时,
//访问RMI服务时将导向本地的x.x.x.90,那么客户端就是访问本地x.x.x.90,
//这绝对错误.服务是在公网路由器(含公共IP)的后面,不在客户的本地
System.setProperty("java.rmi.server.hostname","x.x.x.135");
try {
RMISocketFactory.setSocketFactory(new SMRMISocket()); //定义数据传输端口 8500
LocateRegistry.createRegistry(rmiServerPort); //定义服务注册与查找服务端口 8400
}
catch (Exception ex) {
System.out.println("服务器端口绑定时发生错误:"+ex.getMessage());
ex.printStackTrace();
}
//创建license生成器的服务对象
MakeLicense licenseService = new MakeLicenseService();
//绑定一个服务对象到一个服务端口
//URL format (without the scheme component)
String bindUrl = "//"+hostIP+":"+ rmiServerPort +"/"+bindName;
Naming.rebind(bindUrl, licenseService);
System.out.println(bindUrl+" server is ready.");
////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 = 8500;
System.out.println("RMI服务器的注册与数据传输端口 ="+port);
return new ServerSocket(port);
}
}
////客户端代码:
private String remoteHost = "x.x.x.135"; //公网IP或局域网IP
private int rmiServerPort=8400; //查找服务端口 8400
private String bindName = "licenseServer"; //RMI服务名称
private int revCount = 0;
private MakeLicense remoteObject=null;
public LicenseRequestClient() {
try{
// if(System.getSecurityManager()==null){
// System.setSecurityManager(new RMISecurityManager());
// }
String bindUrl = "//"+remoteHost+":"+ rmiServerPort +"/"+bindName;
System.out.println("请求的远程服务URL="+bindUrl);
MakeLicense remoteObject = (MakeLicense) Naming.lookup(bindUrl);
this.remoteObject = remoteObject;
// System.out.print("远程remoteObject="+remoteObject);
}
catch (RemoteException re) {
System.out.println("RemoteException:" + re);
}
catch (NotBoundException nbe) {
System.out.println("NotBoundException:" + nbe);
}
catch (MalformedURLException mfe) {
System.out.println("MalformedURLException:" + mfe);
}
}
相关文章推荐
- RMI远程调用时的内外网端口映射问题(RMI远程调用如何穿透防火墙)
- RMI远程调用时的内外网端口映射问题(RMI远程调用如何穿透防火墙)
- Juniper NetScreen 防火墙如何做内外网的端口映射
- FMS (端口问题)如何穿透防火墙
- FMS (端口问题)如何穿透防火墙
- JBoss RMI 远程调用需要注意的几个问题!
- Linux下mysql端口不能远程访问的问题(2)-防火墙问题
- 关于RMI远程调用失败的问题
- 远程用户的WSDL访问问题以及SoapUI如何远程调用其他主机上的服务
- Juniper防火墙映射内外网不同端口
- 如何修复在Microsoft Azure中“虚拟机防火墙打开,关闭RDP的连接端口”问题
- 远程拷贝、查看端口、vim常见快捷键、查找替换命令、grep命令、查看存储空间的命令、chkconfig命令、系统自动启动级别、主机名配置、IP地址配置、域名映射、防火墙设置
- 解决远程调用Jmeter需要启动jmeter-server.bat出错的问题【端口被占用】
- 如何修复在Microsoft Azure中“虚拟机防火墙打开,关闭RDP的连接端口”问题
- 远程拷贝、查看端口、vim常见快捷键、查找替换命令、grep命令、查看存储空间的命令、chkconfig命令、系统自动启动级别、主机名配置、IP地址配置、域名映射、防火墙设置
- 穿透防火墙调用EJB--rmi-http在JBOSS中的应用
- 如何修复在Microsoft Azure中“虚拟机防火墙打开,关闭RDP的连接端口”问题
- 如何修复在Microsoft Azure中“虚拟机防火墙打开,关闭RDP的连接端口”问题
- 端口映射不成功,如何找出问题原因
- 如何遥开内外网穿透的问题 --- MCU做简单外网代理