8

我有一个 Windows 服务 - 当它启动时 - 打开一些 WCF 服务来监听 8000 端口。该服务有时会崩溃。当它这样做时,不会释放 TCP 连接,因此如果我尝试再次启动它,我的服务会引发异常:

AddressAlreadyInUseException:IP 端点 0.0.0.0:8000 上已经有一个侦听器

一些观察:

  • 运行CurrPortsnetstat -ano时,我可以看到 8000 端口仍在使用中(处于LISTENING状态),并且由XXX与我的服务进程 ID 对应的进程 ID 拥有。但我的服务已经崩溃,不再出现在任务管理器中。因此我无法终止释放端口的进程!当然,运行taskkill /PID XXX返回:

    错误:找不到进程“XXX”。

  • 运行CurrPortsnetstat -b时,我可以看到创建侦听端口所涉及的进程名称是System,而不是 as MyService.exe(而MyService.exe我的服务正在运行时)。

  • 我尝试使用CurrPorts关闭连接,但总是收到以下错误消息:

    未能关闭一个或多个 TCP 连接。请注意,您必须以管理员身份运行此工具才能关闭 TCP 连接。

    CurrPorts 截图

    (不用说,我确实以管理员身份运行 CurrPorts ......)

  • TCPView也没有太大帮助:8000 端口关联的进程名是<non-existent>,执行“结束进程”或“关闭连接”没有任何效果。

  • XXX我尝试使用Process Explorer查看是否没有与 PID 关联的子进程,但这里没有运气。

  • 如果我正确关闭了我的服务(在它崩溃之前),TCP 连接就会正确释放。这是正常的,因为我会在OnStop()我的服务发生时关闭 WCF 服务主机。


我发现释放连接的唯一方法是重新启动服务器(您可以猜到,这在生产环境中并不方便)。等待没有帮助,TCP 连接永远不会释放。

如何在不重新启动 Windows 服务器的情况下关闭连接?


PS:发现一些 问题和我的非常相似。

4

2 回答 2

2

我遇到了同样的问题,最终发现端口被我的进程子启动的子进程保持打开状态。不知道为什么没有一个系统工具可以告诉我。结束子进程释放端口。

于 2014-12-05T18:46:09.157 回答
0

我建议你尝试 socket.ExclusiveAddressUse=false; 尽管通常不打算解决这种问题。

另一种解决方法 - 找到另一个服务进程并在您的第一行代码中手动终止它。

于 2013-07-03T05:01:35.033 回答