RMI 在 localhost 中同时启动两个服务器,但端口不同
RMI starts two servers in localhost but different port at the same time
我正在学习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
所知道的全部内容。
我正在学习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
所知道的全部内容。