Java RMI 连接使用什么端口?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3071376/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What port is used by Java RMI connection?
提问by kwc
May I know what port is used by Java RMI connection?
我可以知道 Java RMI 连接使用什么端口吗?
If I want to connect a Java client application to a Java server application using RMI connection, what port I need to open at the server machine so that the client application can connect to it?
如果我想使用 RMI 连接将 Java 客户端应用程序连接到 Java 服务器应用程序,我需要在服务器机器上打开什么端口,以便客户端应用程序可以连接到它?
I want to set up a firewall in the server machine but I don't know which port I should open.
我想在服务器机器上设置防火墙,但我不知道应该打开哪个端口。
采纳答案by skaffman
RMI generally won't work over a firewall, since it uses unpredictable ports (it starts off on 1099, and then runs off with a random port after that).
RMI 通常不能在防火墙上工作,因为它使用不可预测的端口(它从 1099 开始,然后使用随机端口运行)。
In these situations, you generally need to resort to tunnelling RMI over HTTP, which is described well here.
在这些情况下,您通常需要借助 HTTP 上的 RMI 隧道,此处对此进行了很好的描述。
回答by Kai Sternad
In RMI, with regards to ports there are two distinct mechanisms involved:
在 RMI 中,关于端口,涉及两种不同的机制:
1) By default, the RMI Registry uses port 1099
1) 默认情况下,RMI 注册表使用端口 1099
2) Client and server (stubs, remote objects) communicate over random ports unless a fixed port has been specified when exporting a remote object. The communcation is started via a socket factory which uses 0 as starting port, which means "use any port that's available" between 0 and 65535.
2) 客户端和服务器(存根、远程对象)通过随机端口进行通信,除非在导出远程对象时指定了固定端口。通信是通过套接字工厂启动的,该工厂使用 0 作为起始端口,这意味着“使用 0 到 65535 之间的任何可用端口”。
回答by El Guapo
You typically set the port at the server using the rmiregistry command. You can set the port on the command line, or it will default to 1099
您通常使用 rmiregistry 命令在服务器上设置端口。可以在命令行设置端口,否则默认为1099
回答by Leo Dagum
If you can modify the client, then have it print out the remote reference and you will see what port it's using. E.g.
如果您可以修改客户端,则让它打印出远程引用,您将看到它使用的端口。例如
ServerApi server = (ServerApi) registry.lookup(ServerApi.RMI_NAME);
System.out.println("Got server handle " + server);
will produce something like:
会产生类似的东西:
Got server handle Proxy[ServerApi,RemoteObjectInvocationHandler[UnicastRef [liveRef: [endpoint:172.17.3.190:9001,objID:[-7c63fea8:...
得到服务器句柄 Proxy[ServerApi,RemoteObjectInvocationHandler[UnicastRef [liveRef: [endpoint:172.17.3.190:9001,objID:[-7c63fea8:...]
where you can see the port is 9001. If the remote class is not specifying the port, then it will change across reboots. If you want to use a fixed port then you need to make sure the remote class constructor does something like:
你可以看到端口是 9001。如果远程类没有指定端口,那么它会在重新启动后发生变化。如果要使用固定端口,则需要确保远程类构造函数执行以下操作:
super(rmiPort)
回答by Paul Vargas
From the javadocof java.rmi.registry.Registry
从javadoc中的java.rmi.registry.Registry
Therefore, a registry's remote object implementation is typically exported with a well-known address, such as with a well-known
ObjID
and TCP port number (default is1099
).
See more in the javadoc of java.rmi.registry.LocateRegistry
.
回答by kevinarpe
The port is available here: java.rmi.registry.Registry.REGISTRY_PORT
(1099)
端口在此处可用:java.rmi.registry.Registry.REGISTRY_PORT
(1099)
回答by Marco Blos
Depends how you implement the RMI, you can set the registry port (registry is a "unique point of services"). If you don't set a explicit port, the registry will assume the port 1099 by default. In some cases, you have a firewall, and the firewall don't allow your rmi-client to see the stubs and objects behind the registry, because this things are running in randomically port, a different port that the registry use, and this port is blocked by firewall - of course.
If you use RmiServiceExporter
to configure your RmiServer, you can use the method rmiServiceExporter.setServicePort(port)
to fixed the rmi port, and open this port in the firewall.
取决于您如何实现 RMI,您可以设置注册表端口(注册表是“唯一的服务点”)。如果您没有设置显式端口,注册表将默认使用端口 1099。在某些情况下,你有一个防火墙,防火墙不允许你的 rmi 客户端看到注册表后面的存根和对象,因为这些东西是在随机端口上运行的,一个注册表使用的不同端口,以及这个端口被防火墙阻止 - 当然。如果你RmiServiceExporter
用来配置你的RmiServer,你可以使用rmiServiceExporter.setServicePort(port)
固定rmi端口的方法,在防火墙中打开这个端口。
Edit: I resolve this issue with this post: http://www.mscharhag.com/java/java-rmi-things-to-remember
编辑:我用这篇文章解决了这个问题:http: //www.mscharhag.com/java/java-rmi-things-to-remember
回答by user207421
All the answers so far are incorrect. The Registry normally uses port 1099, but you can change it. But that's not the end of the story. Remote objects also use ports, and not necessarily 1099.
到目前为止所有的答案都是不正确的。注册表通常使用端口 1099,但您可以更改它。但这并不是故事的结局。远程对象也使用端口,不一定是 1099。
If you don't specify a port when exporting, RMI uses a random port. The solution is therefore to specify a port number when exporting. And this is a port that needs opening in the firewall, if any.
如果导出时不指定端口,RMI 使用随机端口。因此,解决方案是在导出时指定端口号。这是一个需要在防火墙中打开的端口,如果有的话。
In the case where your remote object extends
UnicastRemoteObject
, have its constructor callsuper(port)
with some non-zero port number.In the case where it doesn't extend
UnicastRemoteObject
, provide a non-zero port number toUnicastRemoteObject.exportObject()
.
如果您的远程对象 extends
UnicastRemoteObject
,请super(port)
使用一些非零端口号调用其构造函数。在它不扩展的情况下
UnicastRemoteObject
,为 提供一个非零端口号UnicastRemoteObject.exportObject()
。
There are several wrinkles to this.
这有几个皱纹。
- If you aren't using socket factories, and you provide a non-zero port number when exporting your first remote object, RMI will automatically share that port with subsequently exported remote objects without specified port numbers, or specifying zero. That first remote object includes a Registry created with LocateRegistry.createRegistry().
So if you create a Registry
on port 1099, all other objects exported from that JVM can share port 1099.
- 如果您没有使用套接字工厂,并且在导出第一个远程对象时提供了一个非零端口号,RMI 将自动与随后导出的没有指定端口号或指定为零的远程对象共享该端口。第一个远程对象包括一个使用创建的注册表LocateRegistry.createRegistry().
所以如果您Registry
在端口 1099 上创建一个注册表,那么从该 JVM 导出的所有其他对象都可以共享端口 1099。
If you areusing socket factories, your
RMIServerSocketFactory
must have a sensible implementation ofequals()
for port sharing to work, i.e. one that doesn't just rely on object identity via==
orObject.equals()
.If eitheryou don't provide a server socket factory, oryou do provide one with a sensible
equals()
method, but not both,you can use the same non-zero explicit port number for all remote objects, e.g.createRegistry(1099)
followed by any number ofsuper(1099)
orexportObject(..., 1099)
calls.
如果您正在使用套接字工厂,则
RMIServerSocketFactory
必须有一个合理的实现来equals()
使端口共享工作,即不只依赖于通过==
或的对象标识的实现Object.equals()
。如果要么你不提供服务器套接字工厂,或者你做一个提供一个合理的
equals()
方法,但不能同时,您可以使用相同的非零明确的端口号为所有远程对象,例如createRegistry(1099)
后跟任意数量的super(1099)
或exportObject(..., 1099)
来电.
回答by Nrj
With reference to other answers above, here is my view -
参考上面的其他答案,这是我的观点 -
there are ports involved on both client and server side.
客户端和服务器端都涉及端口。
for server/remote side, if you export the object without providing a port , remote object would use a random port to listen.
a client, when looks up the remote object, it would always use a random port on its side and will connect to the remote object port as listed above.
对于服务器/远程端,如果您在不提供端口的情况下导出对象,远程对象将使用随机端口进行侦听。
客户端,当查找远程对象时,它总是在其一侧使用一个随机端口,并将连接到上面列出的远程对象端口。