在Windows中保留TCP端口 [英] Reserve a TCP port in Windows

查看:689
本文介绍了在Windows中保留TCP端口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想保留一个TCP端口,以便以后由服务绑定,以便Windows在分配随机端口号时不会无意中使用相同的端口号.我知道可以通过注册表和重新启动来实现,但是我想避免这种繁琐的解决方案.

一个进程如何在不实际绑定/侦听该端口的情况下保留端口,然后安全地(即避免出现竞争条件)根据请求将其移交给另一个进程?

不需要预先确定端口号.可以通过第一个过程获取随机端口号并将其传递给请求的过程.

编辑:我发现我的问题陈述得有些拙劣.我真正想要的是将动态端口号的分配与bind-to-port-zero操作分开.这意味着不仅要避免意外随机分配该端口号,而且还要防止任何其他进程在此期间绑定到相同的地址/端口.或者,换一种说法,我希望一个进程开始绑定到端口为零的操作-立即了解将要使用的端口号-并让指定的第二个进程在将来的某个时候完成绑定操作.

目前,我能想到的最接近的解决方法是第一个进程立即绑定到address/0,并保持绑定状态,直到第二个进程请求它为止,此时它解除绑定并告诉另一个进程它获取的端口号,然后将其明确绑定到地址/端口.这有两个问题:1)我宁愿在第二个过程进行之前完全不要绑定; 2)在很小的时间间隔内,第三方可能会意外(或故意)篡夺该端口.

背景

您可能对我为什么想做那么奇怪的事情感到好奇.我一直在调配ZeroMQ,其中一个主要限制是Windows上缺少ipc://传输.令我吃惊的是,端口映射器进程(类似于RPC终结点映射器,或Erlang的epmd)将仅仅是使用tcp://传输和动态端口分配来实现变通方法的票据.但是,允许ZeroMQ客户端和服务器无序连接(即,在服务器绑定之前客户端连接没有错误),所以我试图弄清楚连接的客户端如何能够发现-高度确定性-服务器实际绑定到该端口之前将用于通信的端口.

解决方案

如@vahapt所述,您可以使用netsh修改动态端口范围.

但是,更好的解决方案可能是使用netsh保留应用程序所需的端口,而不必保留动态端口的默认范围.

要这样做:

  1. 在Server 2008/2008 R2上,安装此 Microsoft修补程序.这在Server 2012或更高版本上不是必需的.
  2. 使用保留的端口停止所有进程.如果某个进程正在使用要保留的端口范围内的端口,则NETSH将返回以下错误,并且保留将失败:

    该进程无法访问该文件,因为该文件正在被另一个进程使用.

  3. 使用以下NETSH命令保留端口:

    netsh int <ipv4|ipv6> Add excludedportrange [protocol=]tcp|udp [startport=]<integer> [numberofports=]<integer> [[store=]active|persistent]

    例如,要为UDPv6保留端口55368-55372,请使用以下命令:

    netsh int ipv6 add excludedportrange protocol=udp startport=55368 numberofports=5

注释:

  • 默认情况下,端口保留在重新启动后保持不变
  • 可以为协议的版本4或6保留端口,但不能同时保留两者(即,不能为TCPv4和TCPv6保留端口60000)

请参见 https://support.microsoft.com/en-us/kb/929851 获取更多信息,包括如何查看或删除现有的端口预留.

I'd like to reserve a TCP port, to be bound by a service later, so that Windows doesn't inadvertently use the same number when assigning random port numbers. I know this is possible via the registry and a reboot, but I would like to avoid such a heavy-handed solution.

How can a process reserve a port without actually binding/listening to it, and then safely (i.e., avoiding race-conditions) hand it over to another process on request?

The port number needn't be determined in advance. It's OK for the first process to acquire a random port number, and pass it to the requesting process.

EDIT: It occurs to me that my question is somewhat poorly stated. What I really want is to separate the allocation of a dynamic port number from the bind-to-port-zero operation. This means not just avoiding accidental random allocation of that port number, but also preventing any other process from binding to the same address/port in the interim. Or, putting it another way, I want one process to start the bind-to-port-zero operation — immediately learning the port number that will be used — and let a nominated second process complete the bind operation sometime in the future.

At the moment, the closest work-around I can think of is for the first process to bind to address/0 immediately, and stay bound until the second process requests it, at which point it unbinds and tells the other process the port number it acquired, which then binds to the address/port explicitly. This has two problems: 1) I'd rather not bind at all until the second process comes along; 2) there's a small time interval during which a third party could accidentally (or deliberately) usurp the port.

Background

You may be curious as to why I wish to do something so odd. I've been toying with ZeroMQ, and one major limitation is the absence of the ipc:// transport on Windows. It struck me that a port mapper process (akin to the RPC endpoint mapper, or Erlang's epmd) would be just the ticket to implement a work-around using the tcp:// transport with dynamic port allocations. However, ZeroMQ clients and servers are allowed to connect out of order (i.e., it isn't an error for the client to connect before the server binds), so I am trying to figure out how a connecting client can discover — with a very high degree of certainty — the port that will be used to communicate, before a server actually binds to that port.

解决方案

As mentioned by @vahapt you can modify the dynamic port range using netsh.

However, a better solution may be to use netsh to reserve the ports required by your application, leaving alone the default range of dynamic ports.

To do so:

  1. On Server 2008/2008 R2, install this Microsoft hotfix. This is not required on Server 2012 or later.
  2. Stop any processes using the ports to be reserved. If a process is using a port included in the range of ports to be reserved, NETSH will return the following error and the reservation will fail:

    The process cannot access the file because it is being used by another process.

  3. Use the following NETSH command to reserve the ports:

    netsh int <ipv4|ipv6> Add excludedportrange [protocol=]tcp|udp [startport=]<integer> [numberofports=]<integer> [[store=]active|persistent]

    For example, to reserve ports 55368-55372 for UDPv6, use the command:

    netsh int ipv6 add excludedportrange protocol=udp startport=55368 numberofports=5

Notes:

  • By default port reservations are persistent across reboots
  • Ports may be reserved for either version 4 or 6 of a protocol, but not both (i.e. you cannot reserve port 60000 for both TCPv4 and TCPv6)

See https://support.microsoft.com/en-us/kb/929851 for more information, including how to view or delete existing port reservations.

这篇关于在Windows中保留TCP端口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆