远程方法调用端口被占用。

15

我已经使用RMI创建了一个服务器和客户端程序。但是,无论何时我在命令提示符中启动rmiregistry并运行我的服务器后,都会抛出端口已被使用的错误。只有我自己启动了rmiregistry。我已经从netstat检查过了。

服务器代码:

public class Server implements Runnable, Linker{


private static Server server = null;
    private static Linker l = null;
    private String name = null;
    public Server(){}

    public void setName(String name){
        this.name = name;
    }
    public String getName(){
        return name;               
    }  
    public void run(){
        while(!("Andy").equalsIgnoreCase(name)){

        }
    }
    public static void createStub(){
        try{
            server = new Server();
            l = (Linker) UnicastRemoteObject.exportObject(server, 1099);

            Registry registry = LocateRegistry.getRegistry();
            registry.bind("Link", l);
            System.out.println("Ready");
        }
        catch(Exception e){
            e.printStackTrace();
        }
    }                       
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        createStub();
        Thread t = new Thread(server);

    }
}

客户端代码:

public class Client implements Runnable{


private Scanner sc = new Scanner(System.in);
    private Linker linker = null;

    public void loadStub(){
        try{
            Registry registry = LocateRegistry.getRegistry(1099);
            linker = (Linker) registry.lookup("Link");

        }catch(Exception e){

        }
    }
    public void run(){
        String ip = null;
        while(sc.hasNext()&&!(ip = sc.nextLine()).equalsIgnoreCase(":q")){
            try {
                linker.setName(ip);
            } catch (RemoteException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }


    public static void main(String...args){
        Client client = new Client();
        client.loadStub();
        Thread t = new Thread(client);
        t.start();
    }
}

异常:

java.rmi.server.ExportException: Port already in use: 1099; nested exception is: 
java.net.BindException: Address already in use: JVM_Bind
6个回答

47
如果您使用的是 macOS 操作系统,您可以按照以下步骤停止端口转发:
首先需要找到对应的 PID 编号:lsof -i :1099 然后杀掉该端口:kill -9 PID_number

1
就程序而言,“fwiw -9”基本上是一种“强制退出”。 - Shanimal
不行。这只会杀死需要的 RMI 注册表。你必须找到潜在问题,而不是乱射一通。 - user207421

7

rmiregistry 在其进程中使用端口1099,因此您不能在自己的进程中使用它。您可以采取以下任一措施:

  1. 通过 LocateRegistry.createRegistry() 在同一进程中启动注册表(首选)。
  2. 在不同端口上导出您的对象。
  3. 在1099以外的其他端口上启动 rmiregistry

那在我的情况下就是问题所在。我找到了解决方法,准备在这里发布时发现了你的回复。 netstat -aon 可以显示它正在监听的位置。在这种情况下,它正在监听所有接口。 - Andrews

7
请使用以下服务器代码 -
Registry registry = null;
try {
    registry = LocateRegistry.getRegistry(52365);//use any no. less than 55000
    registry.list();
    // This call will throw an exception if the registry does not already exist
}
catch (RemoteException e) { 
    registry = LocateRegistry.createRegistry(52365);
}

2
为什么小于55000?对于大多数人来说,端口也必须> 1024。最好先尝试创建,如果失败则执行getRegistry())。您的方法存在时间窗口问题。 - user207421
有没有可能做到不使用异常?https://dev59.com/Rm7Xa4cB1Zd3GeqPs7MA - Nelson Tatius
@Lescott 如我所说的那样,在你引用的问题中,不是这样的。 - user207421

0
使用 ps -aef | grep rmiregistry 命令查找 rmiregistry 进程的 PID。 杀掉该进程。 然后再次运行服务器...!!!!

0
请重新检查端口1099是否被其他进程或用户使用,或者在其他端口上启动rmiregistry。

0

试试这个:

lsof -P | grep ':1099' | awk '{print $2}' | xargs kill -9

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接