rmi服务端处于nat后的处理方法

来源:互联网 发布:淘宝直通车通投位置 编辑:程序博客网 时间:2024/06/04 18:18

服务端机器外网IP:*.*.*.7,局域网IP:*.*.*.94

客户端IP:192.168.100.101

服务端rmi注册代码如下,ip为局域网ip:*.*.*.94

System.setProperty("java.rmi.server.hostname",ip);RMISocketFactory.setSocketFactory(new SMRMISocket()); //定义数据传输端口LocateRegistry.createRegistry(8888); //定义服务注册与查找服务端口WorkRemote flowWorkRemote = new WorkRemote();Naming.bind("rmi://"+ip+":8888/rmi",workRemote);

客户端主要代码:

remote = (WorkRemote) Naming.lookup("rmi://"+remoteIP+":8888/rmi");

如果就只是这一句话,则访问时会出现以下错误:

network: 正在使用代理 DIRECT 连接 http://*.*.*.7:8888/network: 正在使用代理 DIRECT 连接 http://*.*.*.94:1100/network: 正在使用代理 DIRECT 连接 http://*.*.*.94:1100/network: 正在使用代理 DIRECT 连接 http://*.*.*.7:8888/network: 正在使用代理 DIRECT 连接 http://*.*.*.94:1100/2013-1-29 10:08:22 ui.MainFrame$1 run严重: nulljava.rmi.ConnectException: Connection refused to host: *.*.*.94; nested exception is: java.net.ConnectException: Connection timed out: connectat sun.rmi.transport.tcp.TCPEndpoint.newSocket(Unknown Source)at sun.rmi.transport.tcp.TCPChannel.createConnection(Unknown Source)at sun.rmi.transport.tcp.TCPChannel.newConnection(Unknown Source)at sun.rmi.server.UnicastRef.invoke(Unknown Source)at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(Unknown Source)at java.rmi.server.RemoteObjectInvocationHandler.invoke(Unknown Source)at $Proxy0.getRoles(Unknown Source)at ui.MainFrame.initData(MainFrame.java:184)at ui.MainFrame.access$1100(MainFrame.java:44)at ui.MainFrame$1.run(MainFrame.java:149)at java.awt.event.InvocationEvent.dispatch(Unknown Source)at java.awt.EventQueue.dispatchEventImpl(Unknown Source)at java.awt.EventQueue.access$000(Unknown Source)at java.awt.EventQueue$1.run(Unknown Source)at java.awt.EventQueue$1.run(Unknown Source)at java.security.AccessController.doPrivileged(Native Method)at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)at java.awt.EventQueue.dispatchEvent(Unknown Source)at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)at java.awt.EventDispatchThread.pumpEvents(Unknown Source)at java.awt.EventDispatchThread.pumpEvents(Unknown Source)at java.awt.EventDispatchThread.run(Unknown Source)Caused by: java.net.ConnectException: Connection timed out: connectat java.net.PlainSocketImpl.socketConnect(Native Method)at java.net.PlainSocketImpl.doConnect(Unknown Source)at java.net.PlainSocketImpl.connectToAddress(Unknown Source)at java.net.PlainSocketImpl.connect(Unknown Source)at java.net.SocksSocketImpl.connect(Unknown Source)at java.net.Socket.connect(Unknown Source)at java.net.Socket.connect(Unknown Source)at java.net.Socket.<init>(Unknown Source)at java.net.Socket.<init>(Unknown Source)at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(Unknown Source)at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(Unknown Source)... 24 more

查看错误信息,发现是访问了服务端的局域网ip导致连接超时的,服务端局域网的ip是客户端根据这句话

remote = (WorkRemote) Naming.lookup("rmi://"+ip+":8888/rmi")获取到的,

故需改写这句,将服务端局域网ip换成服务端外网ip即可,代码如下:

remote = (WorkRemote) Naming.lookup("rmi://"+remoteIP+":8888/rmi");//当服务端位于Nat后时,重新处理接收到的服务端ipRemoteObjectInvocationHandler roih = (RemoteObjectInvocationHandler)Proxy.getInvocationHandler(remote);UnicastRef ref = (UnicastRef)roih.getRef();LiveRef liveRef = ref.getLiveRef();Class[] interfaces = {WorkRemote.class};RemoteObjectInvocationHandler nroih = new RemoteObjectInvocationHandler(new UnicastRef(new LiveRef(liveRef.getObjID(), new TCPEndpoint(remoteIP,liveRef.getPort()), false)));remote = (WorkRemote)Proxy.newProxyInstance(MainFrame.class.getClassLoader(),interfaces, nroih);

改写后,applet控制台的打印信息如下:

basic: 小程序已载入。basic: Applet resized and added to parent containerbasic: PERF: AppletExecutionRunnable - applet.init() BEGIN ; jvmLaunch dt 214852 us, pluginInit dt 432597 us, TotalTime: 647449 usnetwork: 正在使用代理 DIRECT 连接 http://*.*.*.7:8888/network: 正在使用代理 DIRECT 连接 http://*.*.*.94:1100/network: 正在使用代理 DIRECT 连接 http://*.*.*.7:8888/network: 正在使用代理 DIRECT 连接 http://*.*.*.94:1100/network: 正在使用代理 DIRECT 连接 http://*.*.*.7:1100/network: 正在使用代理 DIRECT 连接 http://*.*.*.7:8080/...basic: Applet initializedbasic: 正在载入 Java 小应用程序... basic: 已删除进度监听程序:sun.plugin.util.GrayBoxPainter$GrayBoxProgressListener@578ceb basic: Applet made visiblebasic: Starting appletbasic: completed perf rollupbasic: Applet startedbasic: Told clients applet is started 

在第一次达到这一句时有少许延迟:http://*.*.*.94:1100/,不过最后还是可以访问。

原创粉丝点击