有没有办法在使用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做到这一点,而我只是想念它?

有没有办法在使用System.Net.HttpListener时启用SO_REUSEADDR套接字选项

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

原因是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