有没有办法在使用System.Net.HttpListener时启用SO_REUSEADDR套接字选项
本文关键字:SO 启用 REUSEADDR 选项 套接字 HttpListener Net System 有没有 | 更新日期: 2023-09-27 18:34:00
已经
搜索了一个多小时了,我在文档和网络上的示例中都没有找到如何在使用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
做到这一点,而我只是想念它?
不,您不能将SO_REUSEADDR
与HttpListener
一起使用。
原因是HttpListener
实际上并不管理基础套接字 - 它只是向HTTP.sys
驱动程序注册应用程序级前缀,而驱动程序又管理基础连接。
要使用 SO_REUSEADDR
,您可以创建一个TcpListener
并在底层套接字(可通过 Server
属性访问)上设置 socket 选项,SetSocketOption()
:
$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
)