【问题标题】:How can I free a "daemon" TCP port listener, after its owning process exited?在拥有进程退出后,如何释放“守护程序”TCP 端口侦听器?
【发布时间】:2012-09-04 03:43:48
【问题描述】:

背景

我有一个在 net.tcp 端口 667 上侦听的 .net 4.0 WCF 应用程序。(Windows 7 机器)
在某些时候,应用程序会不正常地退出(例如,用户终止了进程)。
现在发生了一件奇怪的事情:端口仍然打开。当用户重新启动应用程序时,它无法侦听该端口,因为它已经在使用中。

奇怪的是,即使拥有进程被杀死,操作系统并没有关闭端口,甚至在几个小时后也没有。

以下是一些观察:

  • 在 TcpView 上进程为<non-existent>,PID 属于旧(已杀死)进程,状态为LISTENING。本地地址是我的机器,该端口上有 IPV4IPV6 侦听器。
  • TcpView 上的“关闭连接”和“结束进程”操作对该端口没有影响。
  • Process Explorer 不显示旧的(已终止的)进程。我试图搜索 PID 或端口的句柄,但一无所获。
  • 运行netstat -a -b -n -o时,相关的可执行文件显示为System,本地地址为0.0.0.0。其他信息与 TcpView 相同。

我发现关闭该端口的唯一方法是重新启动系统...

问题

  1. 有没有办法配置 WCF net.tcp 服务主机侦听器以避免在进程不正常存在后逗留?
  2. 有没有办法以编程方式关闭该端口?如果有,我的应用程序可以先关闭该端口,然后再尝试监听它。
  3. 是否有可以关闭此类“守护程序”端口的实用程序? (因为 TcpView 不能这样做)
  4. 这是一个操作系统错误吗?操作系统不应该跟踪此类“守护程序”侦听器并在进程存在后关闭它们吗?

【问题讨论】:

标签: wcf tcp


【解决方案1】:

有没有办法配置 WCF net.tcp 服务主机侦听器,以避免在进程不正常存在后挥之不去?

不,至少不应该使用,但是有一种方法可以告诉它在重新启动时重用套接字地址,这样就没有必要了。

有没有办法以编程方式关闭该端口?如果有,我的应用程序可以在尝试侦听之前先关闭该端口。

没有。只有打开端口的应用程序才能关闭它。

是否有可以关闭此类“守护程序”端口的实用程序? (因为 TcpView 做不到)

不,见上文。

这是一个操作系统错误吗?操作系统不应该跟踪此类“守护程序”侦听器并在进程存在后关闭它们吗?

当进程退出时,应该释放所有进程的资源,包括 TCP 端口。 TCP 'ESTABLISHED' 端口有一个例外,出于 TCP 安全原因,它会停留几分钟。

听起来好像有一个子进程继承了仍然处于活动状态的套接字。

【讨论】:

  • 1.如何在 NetTcpBinding 上设置套接字选项?我没有使用原始套接字,而是 WCF net.tcp 绑定。我可以在不更改套接字选项的情况下重用套接字地址吗?
  • 2.我认为这里不涉及子流程。我在Process Explorer中搜索了监听进程的PID,一无所获。
  • @AmirGonnen 我不熟悉那个 API,但大多数网络 API 迟早会让您访问设置套接字选项的方法或套接字本身。一旦您告诉它恢复地址,您就可以重复使用该地址,这就是它的意思。
  • 我不确定 WCF net.tcp 是否如此简单。我添加了一个related question,我们会看到它。到目前为止,我没有得到任何回应。无论如何,谢谢你的回答。
  • @AmirGonnen 哎呀,“恢复”读作“重用”。 iPad 再次来袭。
【解决方案2】:

它也发生在我身上,实际上,我发现是那些持有端口的子进程。我的解决方案是使用 Process Explorer 搜索 Non-existing PID,并杀死所有进程列表,然后端口将空闲。

【讨论】:

  • 试过了,但不幸的是在我的情况下没有子进程并且无法释放端口。
猜你喜欢
  • 2020-07-06
  • 2010-10-07
  • 1970-01-01
  • 1970-01-01
  • 2015-03-18
  • 1970-01-01
  • 1970-01-01
  • 2010-09-08
相关资源
最近更新 更多