【问题标题】:Is there a way to enable the SO_REUSEADDR socket option when using System.Net.HttpListener?有没有办法在使用 System.Net.HttpListener 时启用 SO_REUSEADDR 套接字选项?
【发布时间】:2016-05-21 05:43:33
【问题描述】:

现在已经搜索了一个多小时,但我在文档和网络示例中都没有找到如何在使用 HttpListener 类时启用 SO_REUSEADDR 选项。

我的具体用例在 Powershell 脚本中,但即使 C# 中有答案,那也没问题。这是最简单的:

$Listener = New-Object System.Net.HttpListener
$Listener.Prefixes.Add('http://+:9999/')
Try
{
    $Listener.Start()
    # While loop here to handle requests; omitted for brevity
}
Catch
{
    # omitted here for brevity
}

有时我 Ctrl-C 在测试时跳出脚本,并且以这种方式离开循环不允许调用 $Listener.Stop() 并正确关闭套接字。 (是的,我知道 - 如果它破坏了东西,请不要这样做)

通常,当我需要一个监听套接字时,我会使用SO_REUSEADDR 来处理那些事情没有正确清理的时间,以便让我重新启动我的监听器,而无需等待 30 分钟让端口可用再次。有没有办法用HttpListener 做到这一点而我只是想念它?

【问题讨论】:

  • 肯定会这样做(很惊讶代码还没有,但我继承了它),但它仍然不能解决原来的问题。
  • 我添加了一个答案

标签: c# .net sockets powershell


【解决方案1】:

不,您不能将SO_REUSEADDRHttpListener 一起使用。

原因是 HttpListener 实际上并不管理底层套接字 - 它只是向 HTTP.sys 驱动程序注册应用程序级前缀,而 HTTP.sys 驱动程序又管理底层连接。

要使用SO_REUSEADDR,您可以创建一个TcpListener 并使用SetSocketOption() 在底层套接字上设置套接字选项(可通过Server 属性访问):

$TcpListener = New-Object System.Net.Sockets.TcpListener 9999
$TcpListener.Server.SetSocketOption("Socket", "ReuseAddress", 1)
$TcpListener.Start()

但现在您必须自己实现HttpListener 提供的所有便利功能(标题解析、内容验证等)。


话虽如此,这可能会解决您面临的实际问题:

try{
    $Listener.Start()
}
catch{
}
finally{
    $Listener.Stop()
    $Listener.Dispose()
}

(不要将其粘贴到您的提示符/ISE 中,您需要将其保存到脚本中,或包含在脚本块中,以便在中断时正确评估 finally

【讨论】:

  • 好的,所以我想这只是使用罐装 HttpListener 还是使用 TcpListener 手动完成这一切之间的权衡问题。我有点惊讶 HttpListener 实现没有考虑到这样的事情。添加了 Try/Catch/Finally,因为这似乎是最简单/最快的解决方案。谢谢
  • 我不确定你所说的“考虑到这样的事情”是什么意思 - HttpListener 不是绑定到套接字的那个,它对此无能为力。 HttpListener 实现 IDisposable 来处理释放 http 前缀注册,但由于 PowerShell 中没有 using() 构造,我们将不得不依赖 try/catch/finally
猜你喜欢
  • 2017-05-31
  • 2012-07-12
  • 2020-03-19
  • 2015-07-24
  • 1970-01-01
  • 1970-01-01
  • 2021-06-12
  • 2015-11-05
相关资源
最近更新 更多