C# 生成进程保留套接字端口。如何防止它这样做?
为了简单起见,我正在编写一个名为“应用程序a”的程序,该程序将打开一个到本地主机上8881端口的套接字连接;随后,它使用以下代码生成一个exe应用程序调用“应用程序B”:C# 生成进程保留套接字端口。如何防止它这样做?,c#,sockets,C#,Sockets,为了简单起见,我正在编写一个名为“应用程序a”的程序,该程序将打开一个到本地主机上8881端口的套接字连接;随后,它使用以下代码生成一个exe应用程序调用“应用程序B”: try { XmSam.Log("Spawning (" + process + ")"); ProcessEx proc = new ProcessEx(); proc.StartInfo.FileName = App
try
{
XmSam.Log("Spawning (" + process + ")");
ProcessEx proc = new ProcessEx();
proc.StartInfo.FileName = AppDomain.CurrentDomain.BaseDirectory + process + ".exe";
proc.StartInfo.Arguments = parameters;
proc.StartInfo.UseShellExecute = false;
proc.Start();
Program.Processes.Add(proc);
XmSam.Log("Spawned " + proc.ProcessName);
}
catch (Exception ex)
{
XmSam.Log(ex);
}
当我关闭应用程序A(通过在窗口任务管理器中停止应用程序或终止其进程)时,应用程序B仍在运行,这很好。但是,当我再次启动应用程序A时,出现了一个异常:
2012-10-18 16:21:23 - Only one usage of each socket address (protocol/network address/port) is normally permitted
2012-10-18 16:21:23 - at System.Net.Sockets.Socket.DoBind(EndPoint endPointSnapshot, SocketAddress socketAddress)
应用程序A试图打开端口8881的套接字时发生此错误。如果我杀死应用程序B,这个错误就会消失。我不认为这是因为应用程序B代码,因为它没有如下代码所示的内容:
[STAThread]
static void Main()
{
while (true)
{
}
}
我试着在Process类下查看MSDN,但没有看到任何关于这方面的内容。我假设在生成流程时,该流程独立于调用应用程序,但显然不是这样。您知道有什么设置可以让我生成一个进程,而不让它保留在调用应用程序上吗
我知道另一种方法是让应用程序A中的代码杀死应用程序B,但这不是理想的解决方案,尤其是在应用程序A意外崩溃的情况下
谢谢。您应该确保应用程序A在关闭套接字时将其关闭。我认为Application.ApplicationExit事件是一个很好的执行此操作的地方,或者当您使用完套接字时。经过深入研究,我找到了答案。我觉得这个很棒 其中,对这一问题的主要解释如下: System.Diagnostics.Process.Start使子进程从父进程继承句柄。这意味着,无论您生成什么进程(例如Internet Explorer),该进程都会获得您的进程拥有的所有句柄!因此,即使您释放了流程中的句柄,如果生成的流程仍在运行,您的句柄也不会真正被释放,因为子流程可能正在使用它们 考虑到这一点,我所要做的就是将UseShellExecute标志更新为true
proc.StartInfo.UseShellExecute = true;
当我从程序A中删除生成程序B的代码时,当我杀死程序A时,套接字都正确关闭。我通过查看命令的结果来检查这一点:netstat-aOh和程序A和程序B都是服务应用程序,而不是winform应用程序,因此我不能使用ApplicationExit:(您可以尝试找出为什么仍然存在对套接字的引用,但更简单的解决方案是在适当的时候关闭套接字。我还没有构建服务应用程序,所以我不确定,但我认为服务应用程序也存在一些微笑。