关于RMI局域网连接正常公网无法连接的问题 本帖最后由 zhouyunjie 于 2010-01-26 11:03:36 编辑 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 这个应该是没有问题的,RMI服务器是LINUX,我把防火墙都关了 只是我们公司的防火墙限制了不允许通过公网IP PING入,但其它访问都没有问题。我不知道不允许PING会不会有影响 namingContext.rebind("rmi://192.1698.1.209:7112/sfcl", banrollItem);这句话发贴时弄错了,应该是:namingContext.rebind("rmi://192.168.1.209:7112/sfcl", banrollItem); 这种情况用PING也不能确定是否存在联通性问题。建议使用:telnet XX.XX.XX.139 7112用telnet 可以确定是否 端口可达,而ping只能确定主机可达。说实在的,我一般不用类似:192.1698.1.209的主机地址,这样只能绑定一个地址,而实际外网地址是不绑定的,你用命令windows服务器:netstat -an|find "7112"unix服务器:netstat -an|grep 7112看一下是否绑定了所需地址。最后还有一点不明白的:IP地址192.1698.1.209:7112与IP地址XX.XX.XX.139:7112存在巨大差异,192.1698.1.209这样的地址应该是路由器分配的内网地址,我觉得外网是无法访问的。建议你换成XX.XX.XX.139。不清楚自己说的是否正确,希望楼主等成功解决后能把正确的解决方案贴出来。 192.168.1.209:7112这个是RMI服务器的本机IP我用命令netstat -an|grep 7112 查看确定是绑定的我在其它网络了用telnet XX.XX.XX.139 7112 测试查看也是通的 namingContext.rebind("rmi://xx.xx.xx.139:7112/sfcl", banrollItem);//----------------(3)这个地方如果像上面写用公网IP会提示超时,连接不上,只能改用RMI服务器本机IPnamingContext.rebind("rmi://192.168.1.209:7112/sfcl", banrollItem); 你的RMI server绑定的是一个局域网IP,这个IP地址除了你公司内部网络,其它地方都是不能访问的。 在网上查资料时说RMI服务启动时会产生两个端口,一个是注册端口,一个通讯端口,其中通讯端口是随机的,但我按他们说的固定通讯端口,添加如下代码: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 = 1099; return new ServerSocket(port); }} 2)必须在初始化RMI Server类之前调用下面语句:try { RMISocketFactory.setSocketFactory (new SMRMISocket());} catch (Exception ex) { ... ...} 但我按上面做了后,我在RMI服务器下通过lsof -i:1099命令查看端口1099并没有启动。我想也应该是通讯端口的问题,因为防火墙只能对映射的端口开放。 指定固定端口代码如下:public class RegisterRmi { private static Remote banrollItem=null; public static void startRMI(){ try { if ("false".equals(Config.getProperty("closeRmi"))) { try { RMISocketFactory.setSocketFactory(new SMRMISocket());//固定通讯端口 LocateRegistry.createRegistry(7112);// 注册端口-----(1) System.out.println("客户系统开启rmi 成功!"); } catch (RemoteException e) { System.out.println(e.getMessage()); } //Context namingContext = new InitialContext(); banrollItem = new BanrollItemServerImpl(); //--------------(2) //namingContext.rebind("//192.168.1.209:1099/sfcl", banrollItem);//----------------(3) Naming.rebind("//192.168.1.209:7112/sfcl",banrollItem); } } catch (Exception e) { e.printStackTrace(); } } public static void destoryRMI() { try { UnicastRemoteObject.unexportObject(banrollItem, true); System.out.println("RMI服务已关闭!"); } catch (RemoteException e) { System.out.println("关闭RMI服务失败!"); } }} http://blog.csdn.net/ktyl2000/archive/2009/08/26/4485896.aspx 看这个能解决 http://blog.csdn.net/ktyl2000/archive/2009/08/26/4485896.aspx看了这个后加上下面代码System.setProperty("java.rmi.server.hostname","XX.XX.XX.139");公对公访问是没问题了,但是局域网访问又有问题了,因为我们局域网是不能通过公网IP(XX.XX.XX.139)访问的。问题算是找到了,应该通过设置路由局域网可以用公网IP访问应该就可以访问了 几年前做过RMI,遇到和楼主一样的问题。但是一直没有调试通(客户机和服务机都在公网上,有各自的IP),最后只能放弃了。当初放弃的重要理由是:为何需要通过互联网来访问RMI服务。一般都会有一台公网IP的机器,可以被外面访问,然后就可以使用RMI了(其实就是在内网中使用RMI),没有必要把RMI服务对外公开。同时祝楼主找到了相关方法。 客户机和服务机同在一个网络我真还想不出有其它办法了,因为我们现在做的RMI服务器不光局域网客户机需要用,不同网络公网上的客户同样需要调用。在RMI服务器端下面代码:System.setProperty("java.rmi.server.hostname","XX.XX.XX.139");只能设置一个IP,要么局域网的要么公网IP,设置为局域网IP,公网不能访问。设置公网IP,局域网不能访问。我也曾经尝试过在RMI服务器启动两个服务,一个对局域网一个对公网,分配不同的IP。但好像无法建立不同的通讯IP。有一种办法也许可以解决通过路由设置局域网内也能通过公网IP访问RMI服务机,但无奈的是我公司路由不支持这种设置。暂时只能这样了,如果实在想不出办法只能采取把RMI服务器移到独立的网络上去了。 帮忙写一个正则表达式 我的java学习盘中有两个工作平台,一个是CE一个是ME,请帮助... 有包与无包 写了一个java程序,通过编译器或者命令行都能正确运行,但是做成jar文件就不能运行了?给分 请教用JAVA写传真程序 急急急。。。。。。 有哪个大哥大姐知道java中StringReader()的用法与意义。 简单问题求救!用JBuilder9打包exe文件时遇到的问题,详细请进! NIO写的Socket服务端,用普通的TCP调试工具能用吗 请问Ultraedit+jdk那里有得下载? 请帮忙解决一下,重谢! 打印机号串口握手通信 如何获取JTextField文本框的内容
这句话发贴时弄错了,应该是:
namingContext.rebind("rmi://192.168.1.209:7112/sfcl", banrollItem);
建议使用:telnet XX.XX.XX.139 7112
用telnet 可以确定是否 端口可达,而ping只能确定主机可达。说实在的,我一般不用类似:192.1698.1.209的主机地址,这样只能绑定一个地址,而实际外网地址是不绑定的,你用命令
windows服务器:netstat -an|find "7112"
unix服务器:netstat -an|grep 7112
看一下是否绑定了所需地址。最后还有一点不明白的:IP地址192.1698.1.209:7112与IP地址XX.XX.XX.139:7112存在巨大差异,192.1698.1.209这样的地址应该是路由器分配的内网地址,我觉得外网是无法访问的。建议你换成XX.XX.XX.139。不清楚自己说的是否正确,希望楼主等成功解决后能把正确的解决方案贴出来。
我用命令netstat -an|grep 7112 查看确定是绑定的
我在其它网络了用telnet XX.XX.XX.139 7112 测试查看也是通的
这个地方如果像上面写用公网IP会提示超时,连接不上,只能改用RMI服务器本机IP
namingContext.rebind("rmi://192.168.1.209:7112/sfcl", banrollItem);
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 = 1099;
return new ServerSocket(port);
}
} 2)必须在初始化RMI Server类之前调用下面语句:try {
RMISocketFactory.setSocketFactory
(new SMRMISocket());
} catch (Exception ex) {
... ...
}
但我按上面做了后,我在RMI服务器下通过lsof -i:1099命令查看端口1099并没有启动。
我想也应该是通讯端口的问题,因为防火墙只能对映射的端口开放。
private static Remote banrollItem=null;
public static void startRMI(){
try {
if ("false".equals(Config.getProperty("closeRmi"))) {
try {
RMISocketFactory.setSocketFactory(new SMRMISocket());//固定通讯端口
LocateRegistry.createRegistry(7112);// 注册端口-----(1) System.out.println("客户系统开启rmi 成功!");
} catch (RemoteException e) {
System.out.println(e.getMessage());
}
//Context namingContext = new InitialContext();
banrollItem = new BanrollItemServerImpl(); //--------------(2)
//namingContext.rebind("//192.168.1.209:1099/sfcl", banrollItem);//----------------(3)
Naming.rebind("//192.168.1.209:7112/sfcl",banrollItem); }
} catch (Exception e) {
e.printStackTrace();
}
}
public static void destoryRMI() {
try {
UnicastRemoteObject.unexportObject(banrollItem, true);
System.out.println("RMI服务已关闭!");
} catch (RemoteException e) {
System.out.println("关闭RMI服务失败!");
}
}
}
看这个能解决
看了这个后加上下面代码
System.setProperty("java.rmi.server.hostname","XX.XX.XX.139");
公对公访问是没问题了,但是局域网访问又有问题了,因为我们局域网是不能通过公网IP(XX.XX.XX.139)访问的。
问题算是找到了,应该通过设置路由局域网可以用公网IP访问应该就可以访问了
一般都会有一台公网IP的机器,可以被外面访问,然后就可以使用RMI了(其实就是在内网中使用RMI),没有必要把RMI服务对外公开。同时祝楼主找到了相关方法。
因为我们现在做的RMI服务器不光局域网客户机需要用,不同网络公网上的客户同样需要调用。
在RMI服务器端下面代码:
System.setProperty("java.rmi.server.hostname","XX.XX.XX.139");只能设置一个IP,要么局域网的要么公网IP,
设置为局域网IP,公网不能访问。设置公网IP,局域网不能访问。
我也曾经尝试过在RMI服务器启动两个服务,一个对局域网一个对公网,分配不同的IP。
但好像无法建立不同的通讯IP。
有一种办法也许可以解决
通过路由设置局域网内也能通过公网IP访问RMI服务机,但无奈的是我公司路由不支持这种设置。
暂时只能这样了,如果实在想不出办法只能采取把RMI服务器移到独立的网络上去了。