我在尝试使用RMI在服务器和客户端之间运行通信时遇到了麻烦。我的代码附在下面。服务器运行正常,我可以在pc端口列表中看到监听端口,客户端在registry.lookup上失败。我没有发现任何类似的问题。请帮忙。
服务器:
public class Main {
private static int port = Registry.REGISTRY_PORT;
private static Registry registry;
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
if (args.length == 1) {
try {
port = Integer.parseInt(args[0]);
}
catch (NumberFormatException e) {
System.out.println("Port number is not valid!");
System.exit(0);
}
}
if (System.getSecurityManager() == null)
System.setSecurityManager(new RMISecurityManager());
String name = "DBInterface";
System.out.println("Starting server.");
try {
DBInterface DBInterface = new DBClass();
DBInterface stub = (DBInterface) UnicastRemoteObject.exportObject(DBInterface, 5000);
registry = LocateRegistry.createRegistry(port);
registry.rebind(name, stub);
}
catch (RemoteException e)
{
System.out.println(e.getMessage());
}
System.out.println("Server succesfully started.");
}
}
客户端:
public class Client {
private static String ipAddress = "localhost";
private static int port = Registry.REGISTRY_PORT;
private static String confFile = "";
public static DBInterface dbServer = null;
public static String name = "DBInterface";
public static void main(String[] args) {
System.out.println("Starting client.");
if (System.getSecurityManager() == null)
System.setSecurityManager(new RMISecurityManager());
if (args.length == 3) {
try {
ipAddress = args[0];
port = Integer.parseInt(args[1]);
confFile = args[2];
}
catch (NumberFormatException e) {
System.out.println("Port number is not valid!");
System.exit(0);
}
}
else
{
System.out.println("Some parameter is missing!");
System.out.println("Valid parameters are: IP(0) Port(1) Config_file_name(2).");
}
ArrayList<ArrayList<String>> commands = Tools.loadConfigFile(confFile);
Iterator<ArrayList<String>> commandsIterator = commands.iterator();
Registry registry;
try {
registry = LocateRegistry.getRegistry(ipAddress, port);
dbServer = (DBInterface) registry.lookup(name); //code fails here
} catch (RemoteException e) {
System.out.println(e.getMessage()); //"no such object in table" is printed on the screen
} catch (NotBoundException e) {
System.out.println(e.getMessage());
}
Tools tools = new Tools(dbServer);
...
答案 0 :(得分:1)
你所描述的基本上是不可能的。该异常意味着您正在使用的存根(在本例中为Registry)不再引用目标JVM中的实时导出对象。但是,由于注册表存根是在本地创建的,因此它们根本没有机会到期。唯一的机制是您创建的注册表退出,但静态注册表引用应该阻止它。
我会改变一些事情:
DBInterface stub = (DBInterface) UnicastRemoteObject.exportObject(DBInterface, 5000);
registry = LocateRegistry.createRegistry(port);
反转这两行,并对注册表和导出使用port
。您不需要两个端口。此外,在所有的catch块中,永远不要只是压缩异常消息而不是你自己的。您应始终至少记录实际的异常消息。