0

我在尝试使用 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);

...

4

1 回答 1

1

你描述的基本上是不可能的。该异常意味着您正在使用的存根(在本例中为 Registry)不再引用目标 JVM 中的实时导出对象。但是,由于注册表存根是在本地创建的,因此它们根本没有机会过期。唯一的机制是您创建的注册表退出,但静态注册表引用应该阻止这种情况。

我会改变一些事情:

    DBInterface stub = (DBInterface) UnicastRemoteObject.exportObject(DBInterface, 5000); 
    registry = LocateRegistry.createRegistry(port);

反转这两行,并port用于注册表和导出。您不需要两个端口。此外,在你所有的 catch 块中,永远不要仅仅为了你自己而抑制异常消息。您应该始终至少记录实际的异常消息。

于 2013-04-16T02:28:41.053 回答