【问题标题】:Socket doesn't close after application exits if a launched process is open如果启动的进程打开,应用程序退出后套接字不会关闭
【发布时间】:2012-04-19 19:09:39
【问题描述】:

我的 C# .net 应用程序当前执行以下操作(除其他外):

  1. 创建一个在特定端口上打开套接字并等待指令的线程。
  2. 消息进来,套接字线程读取消息并引发事件。
  3. 事件处理程序调用必要的函数来解析消息并执行必要的操作,例如启动应用程序。
  4. 指定的外部“应用程序”异步启动。

当我的应用程序重新启动,但外部应用程序没有关闭时,套接字似乎永远不会关闭。然后,当我再次尝试在该端口上启动通信时,出现错误。但是,只要我关闭外部应用程序,我就可以在该端口上打开一个套接字。

我的程序似乎没有正常关闭。它应该在退出时杀死套接字,但是当外部进程正在运行时,套接字永远不会关闭。

有什么想法吗?

【问题讨论】:

  • 你在处理socket吗?
  • 你是如何运行外部进程的?请发布一些代码。
  • @M.Babcock 是的,我正在关闭套接字,并且我已经验证了在 UI 关闭时正在执行代码。我正在使用 TcpClient 和 TcpListener。客户端正在“关闭”,侦听器正在“停止”。然而,这似乎并没有释放端口。
  • @zmbq 非常简单——我正在创建一个新的“进程”对象、设置路径、启动它并处理输出。我不等待它关闭,我只是创建它然后去。
  • @nos 我可以尝试等待更长时间。我已经验证,只要我的外部进程(用于测试目的的 firefox)关闭,套接字就会立即关闭,但是只要 firefox 是打开的(到目前为止我已经等了 10 分钟)套接字不会不可用。这可能只是操作系统认为外部应用程序是我的进程的一部分并且不想释放端口的问题。我会在关闭后立即尝试重新打开它,看看会发生什么......

标签: c# .net sockets


【解决方案1】:

这只是一个尝试,因为我已经看到您是如何启动外部进程的。如果你正在创建一个 Process 对象,我猜你没有设置:

ProcessStartInfo.UseShellExecute = true;

如果 UseShellExecute 设置为 false,子进程将从父进程继承打开的套接字句柄。即使父应用程序关闭,这也会让您的套接字保持打开状态。

【讨论】:

  • 正确的钱。 UseShellExecute 被设置为 false,以便我可以重定向/处理输入流。摆脱重定向并将 UseShellExecute 设置为 true 后,端口将被释放。谢谢!
  • 很高兴我能帮上忙。大约一个月前,我们刚刚遇到了这个问题。即使对象正确处理,我们也会在套接字错误后收到套接字错误。幸运的是,这里的一个人发现它埋在 MSDN 的某个地方。
  • 与http://stackoverflow.com/a/24677139/4123833 相同,其中包含另外两个解决方案/选项。
【解决方案2】:

根据我发现的here,我的怀疑可能得到证实,这是新进程从父进程继承句柄的情况,从而导致了您的问题。

看起来您可以从该链接复制/粘贴代码,以直接调用带有标志的 Windows CreateProcess API,以便不继承句柄。

另一个单独的想法是编写一个中间启动器程序,该程序获取命令行信息,然后启动然后退出。这种额外的间接性可能会让您毫不费力地到达您需要的地方。

【讨论】:

  • 看来cmd 非常适合这样的中级启动器,而且工作量极少。
【解决方案3】:

你可以用 using 关键字解决这个问题

using (Socket socket = new Socket()) {
//The code
}

其他应用程序是否使用套接字?

【讨论】:

  • 其他应用程序不使用套接字。我正在使用我系统上的随机应用程序对其进行测试……例如 firefox。
  • 只是为了确保 - 如果您不打开外部应用程序,您的问题是否会释放套接字?
  • 是的,当没有启动外部应用程序时,套接字被释放。
【解决方案4】:

首先要查看应用程序关闭时的套接字状态。套接字可能处于 TIME_WAIT 状态,这意味着它将等待一段时间以确保不会收到其他消息。你可以在这里阅读: http://www.isi.edu/touch/pubs/infocomm99/infocomm99-web/ 现在将在套接字上生成 TIME_WAIT 状态,这取决于它们中的哪一个发起了连接终止过程。因此,如果由于某种原因您的套接字在服务器站点中执行关闭操作,那么在服务器站点(在服务器的端口中),套接字会将状态更改为 TIME_WAIT,因此如果您在套接字处于 TIME_WAIT 期间重新启动服务器应用程序新套接字将无法绑定到侦听端口,我认为这是您遇到的问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-19
    • 1970-01-01
    • 2016-10-31
    • 1970-01-01
    • 2023-03-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多