我有两台电脑。其中一个是运行RMI注册表 - 仅使用此代码创建:
package main;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.Scanner;
public class TheRegistry{
public static void main(String[] args) {
try {
Registry reg = LocateRegistry.createRegistry(2020);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally{
System.out.println("Registry Created");
Scanner input = new Scanner(System.in);
input.nextInt();
System.exit(0);
}
}
}
另一台计算机有一台服务器试图在此注册表上注册一个Object,但是它会出现异常。这是服务器的代码:
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import java.rmi.*;
public class TextScramblerServer implements TextScramblerInterface
{
private static Remote obj;
// main method to export
@Override //Return input text as-is.
public String testInputText(String inputText) {
return "Your input text is: " + inputText;
}
@Override //Return the string reversed.
public String reverse(String inputText) {
String reversedInput = "";
for(int i=0; i<inputText.length();i++)
{
reversedInput=reversedInput+inputText.charAt((inputText.length()-1)-i);
}
return "Result: "+reversedInput;
}
@Override //Return the string scrambled.
public String scramble(String inputText) {
String scrambledInput="";
for(int i=0; i<inputText.length();i++)
{
if(i%2==0)
{
scrambledInput=scrambledInput+inputText.charAt(i);
}
else
{
scrambledInput=inputText.charAt(i)+scrambledInput;
}
}
return "Result: "+scrambledInput;
}
public void exportServer() throws Exception {
System.setSecurityManager(new RMISecurityManager());
obj = UnicastRemoteObject.exportObject(this, 2022);
Registry registry = LocateRegistry.getRegistry("132.205.94.50", 2020);
registry.bind("test", obj);
}
public static void main(String[] args) {
try {
(new TextScramblerServer()).exportServer();
System.out.println("Server is up and running");
}
catch(Exception e){
e.printStackTrace();
try {
UnicastRemoteObject.unexportObject(obj, true); //close port
} catch (NoSuchObjectException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
}
我一直收到错误:
java.rmi.ConnectException: Connection refused to host: 132.205.94.50; nested exception is:
java.net.ConnectException: Connection refused: connect
at 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.newCall(Unknown Source)
at sun.rmi.registry.RegistryImpl_Stub.bind(Unknown Source)
at TextScramblerServer.exportServer(TextScramblerServer.java:57)
at TextScramblerServer.main(TextScramblerServer.java:62)
Caused by: java.net.ConnectException: Connection refused: connect
at java.net.DualStackPlainSocketImpl.connect0(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(Unknown Source)
at java.net.AbstractPlainSocketImpl.doConnect(Unknown Source)
at java.net.AbstractPlainSocketImpl.connectToAddress(Unknown Source)
at java.net.AbstractPlainSocketImpl.connect(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)
... 7 more
java.rmi.NoSuchObjectException: object not exported
at sun.rmi.transport.ObjectTable.unexportObject(Unknown Source)
at java.rmi.server.UnicastRemoteObject.unexportObject(Unknown Source)
at TextScramblerServer.main(TextScramblerServer.java:68)
我无法弄清楚为什么会这样。我想我已经尝试了一切
答案 0 :(得分:1)
我运行了您的代码,它对我有用after configuring the security policy.
您的ConnectionRefused异常表示无法建立基础TCP连接。这是网络问题,而不是RMI问题。
尝试在同一主机上运行服务器和注册表,并使用v[0].indexOf()
作为主机名。如果可行,问题可能是两台主机之间存在防火墙问题。
你可以做一个简单的test of a TCP connection to the specific port using telnet.如果端口没有收听,telnet会给你一个类似的连接拒绝消息。如果端口正在侦听,您将在终端上获得类似的内容:
localhost
Control-C离开会话。
特定的telnet输出可能会因您的操作系统而异,但它们大致相同。
如果是防火墙问题,您必须打开端口。如何做到这一点取决于操作系统,但它很容易找到。
答案 1 :(得分:-1)
您的注册表已被垃圾收集,您的IP地址错误,或者它是公共IP地址,您还没有配置端口转发。
您需要将注册表引用存储在静态对象中以克服垃圾回收,尽管该程序在rmiregistry.exe
已经存在时的重点是让我完全逃脱。
无论如何,你正在咆哮错误的树。您只能绑定到本地主机中运行的RMI注册表。因此,绑定或解除绑定时,永远不需要使用"localhost"
以外的注册表主机名。
你得到NoSuchObjectException
的原因是你试图取消导出由obj
引用的存根,这是UnicastRemoteObject.exportObject()
的结果,它返回存根。见Javadoc。您需要保存new TextScramblerServer()
的结果并取消导出。