RMI 注册表权限被拒绝
RMI Registry permission denied
我正在尝试开始使用 java RMI,但是当我的组件尝试绑定(甚至连接)到 rmiregistry[时,我一直 运行 出错=31=]。每当我尝试将任何东西绑定到 rmiregisrty 时,我都会得到一个 java.rmi.ConnectIOException。老实说,我不知道我需要做什么来解决这个问题。
代码
服务器
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class Server {
public static void main(String[] args) throws Exception {
HelloClass Obj = new HelloClass();
Registry registry = LocateRegistry.getRegistry();
registry.bind("Hello", Obj);
System.out.println("Server is live");
}
}
客户
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class Client {
public static void main(String[] args) throws Exception{
Registry registry = LocateRegistry.getRegistry();
Hello hello = (Hello) registry.lookup("Hello");
String n = hello.Hello();
System.out.println(n);
}
}
你好(界面)
import java.rmi.*;
public interface Hello extends Remote {
public String Hello() throws RemoteException;
}
HelloClass
import java.rmi.server.UnicastRemoteObject;
public class HelloClass extends UnicastRemoteObject implements Hello {
public HelloClass() throws Exception{
super();
}
public String Hello(){
return "Hello world!";
}
}
错误
"C:\Program Files\Java\jdk1.8.0_144\bin\java.exe" "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2019.3.4\lib\idea_rt.jar=57417:C:\Program Files\JetBrains\IntelliJ IDEA 2019.3.4\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_144\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\rt.jar;C:\Users\Roman\Desktop\RMI3\out\production\RMI3" Server
Exception in thread "main" java.rmi.ConnectIOException: Exception creating connection to: 192.168.2.21; nested exception is:
**"C:\Program Files\Java\jdk1.8.0_144\bin\java.exe" "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2019.3.4\lib\idea_rt.jar=57417:C:\Program Files\JetBrains\IntelliJ IDEA 2019.3.4\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_144\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\rt.jar;C:\Users\Roman\Desktop\RMI3\out\production\RMI3" Server
Exception in thread "main" java.rmi.ConnectIOException: Exception creating connection to: 192.168.2.21; nested exception is:
java.net.SocketException: Permission denied: connect
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:631)
at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:216)
at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:202)
at sun.rmi.server.UnicastRef.newCall(UnicastRef.java:338)
at sun.rmi.registry.RegistryImpl_Stub.bind(RegistryImpl_Stub.java:60)
at Server.main(Server.java:15)
Caused by: java.net.SocketException: Permission denied: connect
at java.net.DualStackPlainSocketImpl.connect0(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:79)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:589)
at java.net.Socket.connect(Socket.java:538)
at java.net.Socket.<init>(Socket.java:434)
at java.net.Socket.<init>(Socket.java:211)
at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(RMIDirectSocketFactory.java:40)
at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(RMIMasterSocketFactory.java:148)
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:613)
... 5 more
**
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:631)
at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:216)
at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:202)
at sun.rmi.server.UnicastRef.newCall(UnicastRef.java:338)
at sun.rmi.registry.RegistryImpl_Stub.bind(RegistryImpl_Stub.java:60)
at Server.main(Server.java:15)
Caused by: java.net.SocketException: Permission denied: connect
at java.net.DualStackPlainSocketImpl.connect0(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:79)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:589)
at java.net.Socket.connect(Socket.java:538)
at java.net.Socket.<init>(Socket.java:434)
at java.net.Socket.<init>(Socket.java:211)
at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(RMIDirectSocketFactory.java:40)
at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(RMIMasterSocketFactory.java:148)
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:613)
... 5 more
在服务器 class 中,您正在通过调用 LocateRegistry.getRegistry()
方法检索远程对象注册表引用。
由于未传递主机名和端口,因此内部主机名将使用 java.net.InetAddress.getLocalHost().getHostAddress()
api.
派生
根据错误消息,主机名派生为 192.168.2.21,但在该 IP 上尝试在端口 1099 中创建套接字时出现权限被拒绝错误。
你所在的主机运行服务器class,
那个节点有IP_ADDRESS192.168.2.21吗?
您可以使用
检查
ipconfig /all
您可以使用 java.net.InetAddress.getLocalHost().getHostAddress()
api.
检查
我认为您最好尝试将主机名和端口传递给 LocateRegistry.getRegistry("127.0.0.1",1099)
方法。更改在服务器和客户端代码中。
Server.java
package rmi.learning;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class Server {
public static void main(String[] args) throws Exception {
try {
HelloClass Obj = new HelloClass();
Registry registry = LocateRegistry.getRegistry("127.0.0.1", 1099);
System.out.println("registry=" + registry);
registry.bind("Hello", Obj);
System.out.println("Server is live");
} catch (Exception e) {
e.printStackTrace();
}
}
}
Client.java
package rmi.learning;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class Client {
public static void main(String[] args) throws Exception{
Registry registry = LocateRegistry.getRegistry("127.0.0.1",1099);
Hello hello = (Hello) registry.lookup("Hello");
String n = hello.Hello();
System.out.println(n);
}
}
我已将所有 class 放入 rmi.learning 包中。
Hello.java
package rmi.learning;
import java.rmi.*;
public interface Hello extends Remote {
public String Hello() throws RemoteException;
}
HelloClass.java
package rmi.learning;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
public class HelloClass extends UnicastRemoteObject implements Hello {
protected HelloClass() throws RemoteException {
super();
}
public String Hello() {
return "Hello world!";
}
}
启动 rmi 注册服务
start d:\Java\jdk1.8.0_261\bin\rmiregistry
从命令提示符:
执行服务器
cd d:\workspace_europa\Whosebug\bin
start /B D:\Java\jdk1.8.0_261\bin\java.exe -classpath .;rmi -Djava.rmi.server.codebase=file:rmi/ rmi.learning.Server
输出:
registry=RegistryImpl_Stub[UnicastRef [liveRef: [endpoint:[127.0.0.1:1099](remote),objID:[0:0:0, 0]]]]
Server is live
从命令提示符:
执行客户端
D:\Java\jdk1.8.0_261\bin\java.exe -classpath . rmi.learning.Client
输出:
Hello world!
More investigation:
我试图重现这个问题,我通过路由器连接到互联网。一旦我连接到 wifi,我的路由器就会分配 IP 地址 192.168.0.102。
java.net.InetAddress.getLocalHost().getHostAddress()
api return IP 地址为 192.168.0.102
Wireless LAN adapter Wi-Fi:
Connection-specific DNS Suffix . :
Link-local IPv6 Address . . . . . : xxxx::xxxx:xxxx:xxxx:xxxx%18
IPv4 Address. . . . . . . . . . . : 192.168.0.102
Subnet Mask . . . . . . . . . . . : 255.255.255.0
Default Gateway . . . . . . . . . : 192.168.0.1
如果我尝试将 rmi 服务绑定到端口 1099 中的 192.168.0.102,那么它工作正常。
但是,如果我连接到 VPN,则会为我的主机分配一个新 IP。连接到 VPN 后,IP 192.168.0.102 不再可解析,我的机器 IP_ADDRESS 正在更改。这次如果我尝试将 rmi 服务绑定到 IP 192.168.0.102 然后得到错误 java.net.SocketException: Permission denied: connect.
因此,如果 IP 地址不再适用于当前节点,则会出现错误。
在很多地方我都看到人们建议使用
-Djava.net.preferIPv4Stack=true 也。虽然 运行 Server.class 你可以试试类似的
start /B D:\Java\jdk1.8.0_261\bin\java.exe -Djava.net.preferIPv4Stack=true -classpath .;rmi -Djava.rmi.server.codebase=file:rmi/ rmi.learning.Server
甚至有些地方有人说要在系统上禁用任何防病毒软件 运行,您也可以检查一下这种可能性。
我正在尝试开始使用 java RMI,但是当我的组件尝试绑定(甚至连接)到 rmiregistry[时,我一直 运行 出错=31=]。每当我尝试将任何东西绑定到 rmiregisrty 时,我都会得到一个 java.rmi.ConnectIOException。老实说,我不知道我需要做什么来解决这个问题。
代码
服务器
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class Server {
public static void main(String[] args) throws Exception {
HelloClass Obj = new HelloClass();
Registry registry = LocateRegistry.getRegistry();
registry.bind("Hello", Obj);
System.out.println("Server is live");
}
}
客户
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class Client {
public static void main(String[] args) throws Exception{
Registry registry = LocateRegistry.getRegistry();
Hello hello = (Hello) registry.lookup("Hello");
String n = hello.Hello();
System.out.println(n);
}
}
你好(界面)
import java.rmi.*;
public interface Hello extends Remote {
public String Hello() throws RemoteException;
}
HelloClass
import java.rmi.server.UnicastRemoteObject;
public class HelloClass extends UnicastRemoteObject implements Hello {
public HelloClass() throws Exception{
super();
}
public String Hello(){
return "Hello world!";
}
}
错误
"C:\Program Files\Java\jdk1.8.0_144\bin\java.exe" "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2019.3.4\lib\idea_rt.jar=57417:C:\Program Files\JetBrains\IntelliJ IDEA 2019.3.4\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_144\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\rt.jar;C:\Users\Roman\Desktop\RMI3\out\production\RMI3" Server
Exception in thread "main" java.rmi.ConnectIOException: Exception creating connection to: 192.168.2.21; nested exception is:
**"C:\Program Files\Java\jdk1.8.0_144\bin\java.exe" "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2019.3.4\lib\idea_rt.jar=57417:C:\Program Files\JetBrains\IntelliJ IDEA 2019.3.4\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_144\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\rt.jar;C:\Users\Roman\Desktop\RMI3\out\production\RMI3" Server
Exception in thread "main" java.rmi.ConnectIOException: Exception creating connection to: 192.168.2.21; nested exception is:
java.net.SocketException: Permission denied: connect
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:631)
at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:216)
at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:202)
at sun.rmi.server.UnicastRef.newCall(UnicastRef.java:338)
at sun.rmi.registry.RegistryImpl_Stub.bind(RegistryImpl_Stub.java:60)
at Server.main(Server.java:15)
Caused by: java.net.SocketException: Permission denied: connect
at java.net.DualStackPlainSocketImpl.connect0(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:79)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:589)
at java.net.Socket.connect(Socket.java:538)
at java.net.Socket.<init>(Socket.java:434)
at java.net.Socket.<init>(Socket.java:211)
at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(RMIDirectSocketFactory.java:40)
at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(RMIMasterSocketFactory.java:148)
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:613)
... 5 more
**
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:631)
at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:216)
at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:202)
at sun.rmi.server.UnicastRef.newCall(UnicastRef.java:338)
at sun.rmi.registry.RegistryImpl_Stub.bind(RegistryImpl_Stub.java:60)
at Server.main(Server.java:15)
Caused by: java.net.SocketException: Permission denied: connect
at java.net.DualStackPlainSocketImpl.connect0(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:79)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:589)
at java.net.Socket.connect(Socket.java:538)
at java.net.Socket.<init>(Socket.java:434)
at java.net.Socket.<init>(Socket.java:211)
at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(RMIDirectSocketFactory.java:40)
at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(RMIMasterSocketFactory.java:148)
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:613)
... 5 more
在服务器 class 中,您正在通过调用 LocateRegistry.getRegistry()
方法检索远程对象注册表引用。
由于未传递主机名和端口,因此内部主机名将使用 java.net.InetAddress.getLocalHost().getHostAddress()
api.
根据错误消息,主机名派生为 192.168.2.21,但在该 IP 上尝试在端口 1099 中创建套接字时出现权限被拒绝错误。
你所在的主机运行服务器class,
那个节点有IP_ADDRESS192.168.2.21吗?
您可以使用
检查ipconfig /all
您可以使用 java.net.InetAddress.getLocalHost().getHostAddress()
api.
我认为您最好尝试将主机名和端口传递给 LocateRegistry.getRegistry("127.0.0.1",1099)
方法。更改在服务器和客户端代码中。
Server.java
package rmi.learning;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class Server {
public static void main(String[] args) throws Exception {
try {
HelloClass Obj = new HelloClass();
Registry registry = LocateRegistry.getRegistry("127.0.0.1", 1099);
System.out.println("registry=" + registry);
registry.bind("Hello", Obj);
System.out.println("Server is live");
} catch (Exception e) {
e.printStackTrace();
}
}
}
Client.java
package rmi.learning;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class Client {
public static void main(String[] args) throws Exception{
Registry registry = LocateRegistry.getRegistry("127.0.0.1",1099);
Hello hello = (Hello) registry.lookup("Hello");
String n = hello.Hello();
System.out.println(n);
}
}
我已将所有 class 放入 rmi.learning 包中。
Hello.java
package rmi.learning;
import java.rmi.*;
public interface Hello extends Remote {
public String Hello() throws RemoteException;
}
HelloClass.java
package rmi.learning;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
public class HelloClass extends UnicastRemoteObject implements Hello {
protected HelloClass() throws RemoteException {
super();
}
public String Hello() {
return "Hello world!";
}
}
启动 rmi 注册服务
start d:\Java\jdk1.8.0_261\bin\rmiregistry
从命令提示符: 执行服务器
cd d:\workspace_europa\Whosebug\bin
start /B D:\Java\jdk1.8.0_261\bin\java.exe -classpath .;rmi -Djava.rmi.server.codebase=file:rmi/ rmi.learning.Server
输出:
registry=RegistryImpl_Stub[UnicastRef [liveRef: [endpoint:[127.0.0.1:1099](remote),objID:[0:0:0, 0]]]]
Server is live
从命令提示符: 执行客户端
D:\Java\jdk1.8.0_261\bin\java.exe -classpath . rmi.learning.Client
输出:
Hello world!
More investigation:
我试图重现这个问题,我通过路由器连接到互联网。一旦我连接到 wifi,我的路由器就会分配 IP 地址 192.168.0.102。
java.net.InetAddress.getLocalHost().getHostAddress()
api return IP 地址为 192.168.0.102
Wireless LAN adapter Wi-Fi:
Connection-specific DNS Suffix . :
Link-local IPv6 Address . . . . . : xxxx::xxxx:xxxx:xxxx:xxxx%18
IPv4 Address. . . . . . . . . . . : 192.168.0.102
Subnet Mask . . . . . . . . . . . : 255.255.255.0
Default Gateway . . . . . . . . . : 192.168.0.1
如果我尝试将 rmi 服务绑定到端口 1099 中的 192.168.0.102,那么它工作正常。
但是,如果我连接到 VPN,则会为我的主机分配一个新 IP。连接到 VPN 后,IP 192.168.0.102 不再可解析,我的机器 IP_ADDRESS 正在更改。这次如果我尝试将 rmi 服务绑定到 IP 192.168.0.102 然后得到错误 java.net.SocketException: Permission denied: connect.
因此,如果 IP 地址不再适用于当前节点,则会出现错误。
在很多地方我都看到人们建议使用 -Djava.net.preferIPv4Stack=true 也。虽然 运行 Server.class 你可以试试类似的
start /B D:\Java\jdk1.8.0_261\bin\java.exe -Djava.net.preferIPv4Stack=true -classpath .;rmi -Djava.rmi.server.codebase=file:rmi/ rmi.learning.Server
甚至有些地方有人说要在系统上禁用任何防病毒软件 运行,您也可以检查一下这种可能性。