如何在流程生命周期的最后执行网络IO?

时间:2010-09-27 12:19:55

标签: c++ winapi tcp network-programming winsock

我正在用C ++开发一个DLL,它需要使用write()调用通过(先前建立的)TCP / IP连接写入一些数据。确切地说,当进程发生故障时,DLL应该发送一点'进程12345终止于2007-09-27 15:30:42,i的值为131'消息。

不幸的是,我所知道的用于检测进程结束的所有方式对于任何网络调用都显然为时已晚。特别是,我尝试了以下方法,write()调用在每种情况下返回-1:

  1. 从全局对象的析构函数中调用write()
  2. 从使用write()注册的回调函数调用atexit()
  3. write()致电DllMain(如果reason参数为DLL_PROCESS_DETACH)。我知道这不是一件安全的事情,但我有点绝望。 : - )
  4. 我知道DLL无法检测任何进程关闭(它可能在进程终止之前很久就被卸载)但是因为DLL需要发送的关闭数据取决于其他DLL中的代码,这是可以接受的。我基本上是在寻找可以安全执行网络IO的最新时刻。

    有人知道怎么做吗?

5 个答案:

答案 0 :(得分:3)

考虑从单独的监督程序进程监控流程。

确定进程是否已退出:http://msdn.microsoft.com/en-us/library/y111seb2(v=VS.71).aspx

教程:管理Windows进程:http://msdn.microsoft.com/en-us/library/s9tkk4a3(v=VS.71).aspx

答案 1 :(得分:2)

考虑使用Windows Job Objects

您的主程序(监控程序,将使用例如send())可以启动子进程暂停,将其放入作业然后继续。然后它将在作业对象中运行。您可以SetInformationJobObject通过JobObjectAssociateCompletionPortInformation注册通知。然后,如果在作业中创建了一些子进程并且作业内的某些进程将结束,则会通知您。因此,您将能够从监控过程中发送所需的所有内容。如果在Visual Studio中调试程序,它还使用作业对象来控制您的进程以及您启动的所有子进程。

我在C ++和C#中成功使用了这项技术。因此,如果您在实现方面遇到一些问题,我可以给您发一个代码示例。

答案 2 :(得分:0)

我建议选择3.只需正确加载/卸载DLL,你就可以了。调用write() 应该工作,我无法解释为什么它不在您的情况下。呼叫是否可能因为不相关的其他原因而失败?

如果从主机应用程序手动调用DLL函数,它是否有效?

答案 3 :(得分:0)

为什么呢?只需关闭插座即可。如果这是程序中唯一的关闭,它必须是你的描述,它告诉另一端这个结束正在退出,你可以在开头而不是结束时发送进程ID信息。您不应该在退出挂钩或静态析构函数中执行任何耗时或可能阻塞的操作。

答案 4 :(得分:0)

使用WSACleanup关闭Winsock的位置?在发生这种情况之前,您需要确保I / O完成。

如果发生这种情况,你应该能够通过在Winsock2.dll中的Win32调用上放置一个断点来解决这个问题。卸载DLL将显示在调试窗口的输出中。