当前位置: 首页 > 知识库问答 >
问题:

如何使RMI服务器同时适用于本地客户端(在同一网络中)和外部客户端

越昊穹
2023-03-14

我对Java和RMI还很陌生,所以我决定尝试在我的家用计算机上为聊天客户端设置自己的服务器(只是为了学习的目的,并没有真正的用途)。总而言之,我使用套接字连接来实现消息,使用RMI来实现服务器和客户机之间的通信。问题是我使用的是一个路由器,我想让客户机同时用于外部连接和内部连接(例如,我的笔记本电脑--连接到与服务器相同的路由器)。

我的公共ip是:109.99.33.251
我的本地ip地址是:196.168.1.9
问题是,如果我将java.rmi.server.hostname设置为

  • 服务器本地ip:
    • 一切工作正常,但仅当从本地计算机访问服务器时。
    • 当从外部计算机访问时,只有套接字连接,rmi查找抛出连接拒绝:连接超时。(我想提到的是,我99%确定RMI(1099)和服务器(5000)
    • 端口转发设置正确
    • 当尝试使用服务器的本地ip从本地计算机连接时,套接字连接良好,但rmiregistry查找方法失败。
    • 当使用服务器的公共ip从本地计算机连接时,RMIregistry和套接字都不连接。



    我猜是路由器出了问题。我认为它不支持NAT环回(从具有公共ip的LAN组件访问服务器),因为从本地机器连接到具有公共ip的服务器从来不起作用,即使端口转发设置正确(在外部连接RMI和套接字连接时也起作用)。
    我能做些什么来使这件事成功吗?

    编辑:在服务器端,我在服务器启动后设置System.SetProperty(“java.rmi.server.hostname”,“109.99.33.251”);,然后I:LocateRegistry.CreateRegistry(1099);

    然后绑定对象:

    MyRemote stub= new Communicator();
    registry = LocateRegistry.getRegistry();
    registry.bind("comm", stub);
    

    其中MyRemote是扩展Remote接口的接口,Communicator是:

    public class Communicator extends UnicastRemoteObject implements MyRemote
    {
        public Communicator() throws RemoteException
        {
            super(Registry.REGISTRY_PORT);
            System.out.println("I've created the host");
        }
        //the methods in the MyRemote
    }`
    



    对于我使用的套接字:

    ServerSocket serverSock = new ServerSocket(5000);
    while(true) 
    {
        Socket clientSocket = serverSock.accept();
        ClientHandler handler =new ClientHandler(clientSocket);
        clients.add(handler);
        Thread t = new Thread(handler);
        t.start();
        System.out.println("got a connection");
    }
    



    对于客户端查找:service=(MyRemote)naming.lookup(“rmi://”+serverIp+“/comm”);
    对于套接字连接socket socket=new socket(serverIp,new Integer(serverPort));
    serverIp保存服务器的公共ip或本地ip(具体情况取决于前面介绍的情况)。且serverport为5000

    为了让自己明白,我希望客户机在本地和外部机器上都能工作,所以我正在寻找一种方法来绑定远程对象并设置连接,以使两者都能工作(如果可能的话)。

    注意:很抱歉,我对网络、java和这个站点都是新手,所以请不要介意我在提问时犯的错误。提前谢谢!

    最后编辑:我已经联系了我的ISP,他们说路由器有其最新的固件版本,它只是不支持NAT环回。

共有1个答案

晁聪
2023-03-14

不幸的是,Oracle/Sun RMI实现在这方面稍有缺陷。存在一个不必要的深层假设,即存在一个对所有客户端可见的IP地址。您必须将java.rmi.server.hostname设置为NAT外部的公共IP地址,并且内部客户端必须能够使用该地址。

 类似资料:
  • 我有一个客户端服务器的情况,每一方都在测量时间,但似乎有一个问题,即测量的时间不匹配。长话短说,这个想法是有一个倒计时,之后程序需要做事情。我在服务器端测量这个。但是,倒计时需要显示,所以我所做的是在客户端单独运行它。最终结果是,当服务器发送消息时,客户端显示为23秒,该消息表明时间倒计时为10分钟。 客户端为XNA,代码: 然后从可用时间中减去计时器,并显示出来。在服务器端,这种情况正在发生:

  • 我在客户端wnat纯java RMI,因为我需要能够重新启动服务器端。

  • 问题内容: 我是一个优秀的程序员,但是我的网络经验为零。 基本上,我想进入客户端- 服务器网络。例如,我想尝试运行一个服务器进程,该进程允许客户端通过Internet连接并将ping发送到所有其他连接的客户端。然后,也许我将尝试开发一个简单的聊天客户端,或一些简单的多人游戏,然后从那里开始。 我非常了解可能有用的语言:Java,C ++,C。 我该如何开始?我想提前学习最佳实践,因此您可以推荐的良

  • 问题内容: 如果我想在我的RMI应用程序中启用“双向”通信(即,允许服务器调用客户端上的方法,以及允许客户端调用服务器上的方法),则是使客户端成为还有远程课程吗? 另外,如果我打算将客户端的实例作为方法参数传递给服务器,我是否认为不需要在rmiregistry中添加“客户端类”是正确的吗? 最后一个问题,我所有的类是否仍需要在同一位置编译?IE可以在两台完全独立的计算机上编译服务器和客户端,并期望

  • 我构建了一个基于文件下载器RMI客户端-服务器的应用程序。在这方面,我不了解不同客户端的工作。文件位于服务器端,RMI在其一侧有等效的代理服务器(称为存根)。我为这个应用程序使用了10个客户端和1个服务器。 问题1-我的问题是当多个客户端在从注册表查找后同时进行RMI调用时,客户端以什么顺序为他们播种/提供文件?意味着底层服务算法---? 我无法理解这一点,当我执行代码时,我只看到相应的文件正在同

  • 问题内容: 我正在使用RMI编写密码系统的原型。 我有一个问题,因为当我启动两个客户端时,它们从OneTimePad类的服务器中的一个对象获得了响应。 因此客户端A获取为客户端b保留的密钥,由于特定的算法,这种情况不会发生。 服务器仅向客户端发送E和N变量(例如在RSA中),因此我无法序列化OneTimePad对象并通过网络发送它(因为它将具有所有密钥)。 如何为每个客户端创建OneTimePad