簡體   English   中英

Java RMI 在 LAN 中工作時無法通過 WAN 連接到服務器

[英]Java RMI cannot connect to server via WAN while it works in LAN

我正在開發一個使用 Java RMI 和客戶端-服務器實現的項目。 在服務器端,這是我初始化服務器的方式:

final String url = "localhost";
            final int port = 8090;
            LocateRegistry.createRegistry(port);
            IServerGame serverGame = new ServerGame();
            Naming.rebind("//"+url+":"+port+"/undercover", serverGame);
            System.out.println("Server running at //" + url + ":" + port + "/undercover") 

Undercover 是我的應用程序的名稱。 我們隨意選擇使用8090端口。 現在,這是我初始化連接客戶端的方法:

try {
            server = (IServerGame) Naming.lookup("//"+address+":8090/undercover");
            System.out.println("Connected to server " + address + ".");
        } catch (Exception e) {
            System.out.println("Connection failed.");
            e.printStackTrace();
        }

address是初始化連接的方法參數中的字符串,是服務器的IP。 我們要求客戶端輸入此 IP 以允許我們根據需要連接到不同的服務器。

當我在本地運行我的應用程序時,無論我使用 localhost 還是我的私有 IP 192.168.xx 作為address ,一切正常。 客戶端連接到服務器,我可以使用該應用程序。 問題是,當我想通過 WAN 使用該應用程序時,將客戶端發送給朋友並在我的本地機器上啟動服務器時,它不再工作了。 我收到此錯誤:

java.rmi.ConnectException: Connection refused to host: (private IP of host machine); nested exception is: 
java.net.ConnectException: Connection timed out: connect

我已經用完全相同的問題檢查了 StackOverflow 中的很多帖子,通常的答案是設置SystemProperty(java.rmi.server.hostname,"192.168.xx")或通過-Djava.rmi.server.hostname在命令行中。 我正在使用 Gradle 進行編譯。 我通過運行任務運行應用程序。 客戶端也是一個基本的外匯應用程序。 不幸的是,這些都不起作用。 我也嘗試在我的防火牆中打開端口 8090 但它也沒有解決問題。 現在也許我做錯了。 我還嘗試用我的公共 IP 79.95.xx 替換我的私有 IP 192.168.xx,這是我通過命令 shell 中的ipconfig找到的 IPv4 但是,它再次不起作用。 我嘗試添加SystemProperty(java.rmi.server.hostname,"192.168.xx")就像我上面向您展示的服務器代碼中出現的第一行代碼一樣。 我通過 4G 連接到互聯網。 我沒有盒子連接,所以我不能真正進入盒子設置以允許某些端口,如果這可以解決問題的話。

編輯 :

所以我嘗試從服務器端的命名實現切換到注冊表實現,正如下面建議的那樣,但它沒有任何區別。 因為我認為這可能只是一個連接問題,所以我讓一個朋友在端口 8090 上使用 telnet ping 服務器,但實際上它不起作用。 他運行 telnet [域名或 ip] [端口] 並且錯誤是:

Unable to connect to remote host: Connection timed out

所以問題是外部客戶端無法訪問我的服務器或連接到端口。 正如我上面提到的,我使用 4G 作為互聯網連接,關於如何使端口可達的任何想法?

嘗試使用類java.rmi.registry.Registry而不是類java.rmi.Naming

在服務器端:

final int port = 8090;
Registry registry = LocateRegistry.createRegistry(port);
ServerGame serverGame = new ServerGame();
IServerGame stub = (IServerGame) UnicastRemoteObject.exportObject(serverGame, 0);
registry.bind("undercover", stub);

在客戶端:

Registry registry = LocateRegistry.getRegistry("server host name or IP", 8090);
IServerGame serverGame =  (IServerGame) registry.lookup("undercover");

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM