2010-02-09 87 views
7

在Java中,我需要获取用于同一程序的多个实例之间通信的端口号。 现在,我可以简单地选择一些固定的数字,并与它一起去。但是我想知道是否有办法动态选择端口号,这样我就不必为设置端口号而困扰我的用户了。动态选择端口号?

这里是我有一个想法,它的工作原理是这样的:

  • 有一个固定的初始端口号A.
  • 计划“MyApp的”开始,试图抢口A.
  • 如果成功,那么它就是'MyApp'的第一个实例。完成。
  • 如果失败,它会通过端口A询问A上的程序是否为'MyApp'的实例。如果是,则与该实例进行通信。完成。如果不是,请尝试抓取端口A + 1。如果有另一个程序使用该端口(不是'MyApp'的实例),那么抓住A + 2,然后抓住A + 3,等等。

此策略是否有意义?还是有更好的方法来动态选择一个端口号?

+1

你不需要这样做。如果您创建套接字,系统会自动为您分配下一个可用的端口号。请仔细阅读您正在使用的套接字API的文档。还提供更多关于您正在使用的编程语言/库的标签。 – 2010-02-09 18:39:16

+0

@dma_k:在Java中,显然你必须绑定到端口0来实现(反直觉,我知道)。如果你根本不绑定,你将无法听到它。 :-P – 2010-02-09 18:41:36

+0

几乎所有我能记得的socket实现使用这个“反直觉”技巧来请求一个动态分配的端口......这里没什么特别的。 – jldupont 2010-02-09 18:48:10

回答

26

如果绑定到端口0,则Java将使用系统生成的端口。 :-)所以,如果你已经使用了你想要的端口,这可能是最简单的方法。

ServerSocket s = new ServerSocket(0); 
int port = s.getLocalPort(); // returns the port the system selected 
+2

...以及实例如何找到对方?这不就是问题的全部? – jldupont 2010-02-09 18:46:30

3

我会采取相反的做法,并为您的应用程序选择一个固定的高端口。将其设置为配置值,以便在必要时进行更改。这将简化配置,因为应用程序的用户通常需要请求网络操作来打开端口。围绕IANA分配的值工作:

http://www.iana.org/assignments/port-numbers

扫描端口,可以把你的应用程序变成一个坏公民对许多入侵检测系统。

1

您可以使用Bonjour/ZeroConf来通告每个实例的服务并使实例能够找到其他实例。将其视为目录服务,它可以帮助管理您的端口名称空间。

在这种情况下,每个实例只能获取动态分配的端口。绑定到端口“0”的请求通常会指示系统分配一个动态端口。