gpt4 book ai didi

java - RMI 在本地主机中同时启动两个服务器,但端口不同

转载 作者:行者123 更新时间:2023-12-02 11:35:02 29 4
gpt4 key购买 nike

我正在学习RMI,想知道是否可以启动两个具有不同端口的服务器,以及如何实现?

该程序有一个客户端和两个服务器。 Server1使用RMI默认端口1099。Server2使用端口1098(我检查过端口1098没有被使用)。

服务器1:

public static void main(String[] args) {
try {
Server obj = new Server();
Hello stub = (Hello) UnicastRemoteObject.exportObject(obj, 0);

Registry registry = LocateRegistry.getRegistry();
registry.bind("Hello", stub);

System.out.println("Server 1 ready");
} catch (Exception e){
System.err.println("Server exception: " + e.toString());
e.printStackTrace();
}
}

服务器2

public static void main(String[] args) {
try {
ServerTwo obj = new ServerTwo();
HelloTwo stub = (HelloTwo) UnicastRemoteObject.exportObject(obj, 0);

Registry registry = LocateRegistry.createRegistry(1098);
registry = LocateRegistry.getRegistry(1098);
registry.bind("HelloTwo", stub);

System.out.println("Server 2 ready");
} catch (Exception e){
System.err.println("Server exception: " + e.toString());
e.printStackTrace();
}
}

编译并运行服务器:

javac *java
rmic Server
rmiregistry 1099 &
rmic ServerTwo
rmiregistry 1098 &

顺便说一句,1099和1098端口的进程名是不同的。我通过lsof -i tcp:portnumber检查端口,发现端口1099和1098分别有两个进程。但端口 1099 显示名称为 *:rmiregistry (LISTEN)。端口 1098 显示名称为 *:rmiactivation (LISTEN)。为什么它们不同?这是什么意思?这与以下错误有关吗?

启动Server2时,出现以下错误:

Server exception: java.rmi.server.ExportException: Port already in use: 1098; nested exception is: 
java.net.BindException: Address already in use
java.rmi.server.ExportException: Port already in use: 1098; nested exception is:
java.net.BindException: Address already in use
at sun.rmi.transport.tcp.TCPTransport.listen(TCPTransport.java:341)
at sun.rmi.transport.tcp.TCPTransport.exportObject(TCPTransport.java:249)
at sun.rmi.transport.tcp.TCPEndpoint.exportObject(TCPEndpoint.java:411)
at sun.rmi.transport.LiveRef.exportObject(LiveRef.java:147)
at sun.rmi.server.UnicastServerRef.exportObject(UnicastServerRef.java:208)
at sun.rmi.registry.RegistryImpl.setup(RegistryImpl.java:152)
at sun.rmi.registry.RegistryImpl.<init>(RegistryImpl.java:137)
at java.rmi.registry.LocateRegistry.createRegistry(LocateRegistry.java:203)
at ServerTwo.main(ServerTwo.java:20)
Caused by: java.net.BindException: Address already in use
at java.net.PlainSocketImpl.socketBind(Native Method)
at java.net.AbstractPlainSocketImpl.bind(AbstractPlainSocketImpl.java:382)
at java.net.ServerSocket.bind(ServerSocket.java:375)
at java.net.ServerSocket.<init>(ServerSocket.java:237)
at java.net.ServerSocket.<init>(ServerSocket.java:128)
at sun.rmi.transport.proxy.RMIDirectSocketFactory.createServerSocket(RMIDirectSocketFactory.java:45)
at sun.rmi.transport.proxy.RMIMasterSocketFactory.createServerSocket(RMIMasterSocketFactory.java:345)
at sun.rmi.transport.tcp.TCPEndpoint.newServerSocket(TCPEndpoint.java:666)
at sun.rmi.transport.tcp.TCPTransport.listen(TCPTransport.java:330)
... 8 more

显示端口1098正在使用...是的,Server2使用了该端口...如何解决?我对 RMI 和端口连接感到困惑。

============

编辑:

添加客户端代码:

public static void main(String[] args) {
String host = (args.length < 1) ? null : args[0];

try {
Registry registry = LocateRegistry.getRegistry(host);
Hello stub = (Hello) registry.lookup("Hello");
String response = stub.sayHello();
System.out.println("response 1: " + response);

HelloTwo stub2 = (HelloTwo) registry.lookup("HelloTwo");
String response2 = stub2.sayHello();
System.out.println("response 2: " + response2);

} catch (Exception e) {
System.err.println("Client exception: " + e.toString());
e.printStackTrace();
}
}

最佳答案

您不需要两个注册表。如果注册表和远程对象都是由同一个 JVM 创建的,您甚至不需要两个端口。您只需要:

  • 将两个远程对象放入同一个 JVM
  • 调用LocateRegistry.createRegistry(Registry.REGISTRY_PORT)
  • 然后然后创建并导出两个远程对象。

这样,所有内容都将监听端口 1099。

The port 1098 shows the name is *:rmiactivation (LISTEN). Why they are different?

因为端口 1098 是为 RMI 激活守护进程保留的,而这就是 lsof 所知道的全部内容。

关于java - RMI 在本地主机中同时启动两个服务器,但端口不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49004346/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com