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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 16:12:42  来源:igfitidea点击:

What port is used by Java RMI connection?

javaconnectionrmifirewall

提问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 ObjIDand TCP port number (default is 1099).

因此,注册表的远程对象实现通常使用众所周知的地址导出,例如使用众所周知的ObjIDTCP 端口号(默认为1099)。

See more in the javadoc of java.rmi.registry.LocateRegistry.

.javadoc 中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 RmiServiceExporterto 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 call super(port)with some non-zero port number.

  • In the case where it doesn't extend UnicastRemoteObject, provide a non-zero port number to UnicastRemoteObject.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 Registryon 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 RMIServerSocketFactorymust have a sensible implementation of equals()for port sharing to work, i.e. one that doesn't just rely on object identity via ==or Object.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 of super(1099)or exportObject(..., 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.

  • 对于服务器/远程端,如果您在不提供端口的情况下导出对象,远程对象将使用随机端口进行侦听。

  • 客户端,当查找远程对象时,它总是在其一侧使用一个随机端口,并将连接到上面列出的远程对象端口。