如何在 C# 中的随机端口上创建 HttpListener 类?
我想创建一个在内部提供网页服务的应用程序,并且可以在同一台计算机上的多个实例中运行。 为此,我想创建一个 HttpListener
来侦听以下端口:
- 随机选择
- 当前未使用
本质上,我想要的是:
mListener = new HttpListener();
mListener.Prefixes.Add("http://*:0/");
mListener.Start();
selectedPort = mListener.Port;
我怎样才能完成这个?
I would like to create an application that serves web pages internally and can be run in multiple instances on the same machine. To do so, I would like to create an HttpListener
that listens on a port that is:
- Randomly selected
- Currently unused
Essentially, what I would like is something like:
mListener = new HttpListener();
mListener.Prefixes.Add("http://*:0/");
mListener.Start();
selectedPort = mListener.Port;
How can I accomplish this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
如果绑定到端口 0,TcpListener 将随机查找一个未使用的端口来侦听。
TcpListener will find a random un-used port to listen on if you bind to port 0.
像这样的事情怎么样:
我不确定如何找到该机器上正在使用的所有端口,但是如果您尝试侦听已在使用的端口,在这种情况下,您应该会得到一个异常该方法将简单地选择另一个端口。
How about something like this:
I'm not sure how you would find all of the ports that are in use on that machine, but you should get an exception if you try to listen on a port that is already being used, in which case the method will simply pick another port.
这是一个答案,源自 Snooganz 的答案。 它避免了可用性测试和后续绑定之间的竞争条件。
在我的机器上,此方法平均需要 15 毫秒,这对于我的用例来说是可以接受的。 希望这对其他人有帮助。
Here's an answer, derived from Snooganz's answer. It avoids the race condition between testing for availability, and later binding.
On my machine this method takes 15ms on average, which is acceptable for my use case. Hope this helps someone else.
由于您使用的是 HttpListener(因此也是 TCP 连接),您可以使用
IPGlobalProperties
对象的GetActiveTcpListeners
方法获取活动 TCP 侦听器的列表,并检查它们的Port< /代码> 属性。
可能的解决方案可能如下所示:
此代码将从
startingPort
端口号开始找到第一个未使用的端口,并返回true
。 如果所有端口都已被占用(这种情况不太可能发生),该方法将返回false
。另请记住,当其他进程先于您获取找到的端口时,可能会发生竞争条件。
Since you are using an HttpListener (and therefore TCP connections) you can get a list of active TCP listeners using
GetActiveTcpListeners
method of theIPGlobalProperties
object and inspect theirPort
property.The possible solution may look like this:
This code will find first unused port beginning from the
startingPort
port number and returntrue
. In case all ports are already occupied (which is very unlikely) the method returnsfalse
.Also keep in mind the possibility of a race condition that may happen when some other process takes the found port before you do.
不幸的是,这是不可能的。 正如 Richard Dingwall 已经建议的那样,您可以创建一个 TCP 侦听器并使用该端口。 这种方法有两个可能的问题:
Unfortunately, this isn't possible. As Richard Dingwall already suggested, you could create a TCP listener and use that port. This approach has two possible problems:
我建议尝试 Grapevine。 它允许您在应用程序中嵌入 REST/HTTP 服务器。 它包含一个
RestCluster
类,允许您在一个位置管理所有RestServer
实例。将每个实例设置为使用随机的开放端口号,如下所示:
入门指南: https://sukona.github.io/Grapevine/en/getting-started.html
I'd recommend trying Grapevine. It allows you embed a REST/HTTP server in your application. It includes a
RestCluster
class that will allow you to manage all of yourRestServer
instances in a single place.Set each instance to use a random, open port number like this:
Getting started guide: https://sukona.github.io/Grapevine/en/getting-started.html
我不相信这是可能的。 UriBuilder.Port 的文档指出,“如果未将端口指定为 URI 的一部分,...协议方案的默认端口值将用于连接到主机。”。
请参阅 https://msdn.microsoft .com/en-us/library/system.uribuilder.port(v=vs.110).aspx
I do not believe this is possible. The documentation for UriBuilder.Port states, "If a port is not specified as part of the URI, ... the default port value for the protocol scheme will be used to connect to the host.".
See https://msdn.microsoft.com/en-us/library/system.uribuilder.port(v=vs.110).aspx