将地址和端口绑定到 RMI

Bind address and port to RMI

我正在开发聊天功能,首先我使用套接字和流在服务器和客户端之间进行通信,我已经与我的朋友一起测试过它并且有效。现在我正在尝试转换为 RMI。

所以,它在本地工作,但是当我的朋友尝试连接时,他得到了拒绝连接。奇怪的是它显示服务器本地 ip (192.168.25.28)。

我的代码如下所示:

    public void conectar() throws RemoteException, MalformedURLException, NotBoundException{
    // COMUNICADOR SERVIDOR (USADO PELO CLIENTE)
    comunicadorServidor = new ComunicadorServidor(id); // cria um novo comunicador
    LocateRegistry.createRegistry(8081); // inicia o registro RMI na porta 8081
    Naming.rebind("//:8081/ComunicadorServidor", comunicadorServidor); // vincula o objeto comunicador ao endereço RMI
    // COMUNICADOR CLIENTE (USADO PELO SERVIDOR)
    comunicador = (IComunicadorCliente) Naming.lookup("//" + conexao.getInetAddress().getHostAddress() + ":8082/ComunicadorCliente"); // procura o comunicador no cliente
}

所以我在服务器和客户端都使用 RMI,并且一个相互连接,因为在服务器中我有客户端使用的身份验证和发送消息等方法,在客户端中我有更新用户列表等方法和服务器使用的接收消息。

因此,首先我创建了一个 RMI class 实例(服务器端),在端口 8081 上创建了一个注册表,然后使用名称 "ComunicadorServidor".[= 将对象绑定到端口 8081 11=]

然后服务器尝试连接到客户端 RMI。

所以我看了rebind的方法,如果不指定地址,它会绑定到本地主机地址,我问:即使绑定到我的本地机器,它在外面是否仍然可用?如果没有,我怎样才能将它绑定到与套接字相同的地方,我只需要指定一些端口,它就可以用于任何地址,比如本地主机、本地 ip 或外部 ip。

关于查找,获取客户端 IP 的最佳方式是什么(现在我从套接字获取),我如何确定我将获得正确的 IP?我可以在没有套接字的情况下连接到客户端 RMI 吗?

在客户端,它本质上是一样的,除了它将 RMI class 绑定到 8082 并在服务器端使用提供的 IP 和端口查找 RMI class。

Weirder is that it shows the server local ip (192.168.25.28).

没错。如果您需要它出现在 public IP 地址上,您需要查找 java.rmi.server.hostname,并查看 RMI FAQ 中的 A.1 项。

So I read about the rebind method, and if I don't specify an address, it will bind to the local host address, which I ask: even if it's binding to my local machine, is it still available outside?

如果服务器端防火墙规则允许,外部世界可以使用注册表。请注意,RMI 意义上的 bind 仅表示将远程对象与注册表中的名称相关联:它与 Socket.bind().

无关

And about the lookup, what is the best way to get the client IP (right now I'm taking from the socket), how can I be sure that I will get a correct IP? Can I connect to the client RMI without a socket?

你根本不能在 RMI 中 'connect',但你不需要客户端的 IP 地址。客户端应通过服务器远程方法向服务器注册其远程对象,例如register(Client client) throws RemoteException。然后服务器有一个存根,它可以在上面直接调用客户端远程方法(客户端防火墙允许)。