system函数的问题

来源:互联网 发布:网络共享打印机搜不到 编辑:程序博客网 时间:2024/06/13 11:59

最近碰到这样一个问题:

进程退出了,进程某个监听的端口还在监听状态,这个进程比较特殊,用system("start ")命令打开了其他的一些进程,然后该进程退出,用netstat发现该进程pid还在监听一个端口,但是任务管理器看不到这个进程pid了,然后把system打开的所有进程都关掉,我中间一个一个关发现直到最后一个进程关掉,这个端口才解除监听

最后调试跟踪system函数,发现system函数里面最终还是调用了

BOOL WINAPI CreateProcess(
  __in          LPCTSTR lpApplicationName,
  __in_out      LPTSTR lpCommandLine,
  __in          LPSECURITY_ATTRIBUTES lpProcessAttributes,
  __in          LPSECURITY_ATTRIBUTES lpThreadAttributes,
  __in          BOOL bInheritHandles,
  __in          DWORD dwCreationFlags,
  __in          LPVOID lpEnvironment,
  __in          LPCTSTR lpCurrentDirectory,
  __in          LPSTARTUPINFO lpStartupInfo,
  __out         LPPROCESS_INFORMATION lpProcessInformation
);

这个函数调用的cmd.exe,而CreateProcess的参数bInheritHandles是填的TRUE,参照msdn对bInheritHandles的解释

If this parameter TRUE, each inheritable handle in the calling process is inherited by the new process. If the parameter is FALSE, the handles are not inherited. Note that inherited handles have the same value and access rights as the original handles.

如果该参数为TRUE那么子进程继承父进程所有能继承的句柄,而且拥有父进程同样的句柄值和权限


所以这个bug的产生的原因大概也明了了,我这个进程所监听的端口socket被继承到cmd.exe中,然后cmd通过start(start里面应该也是调用的CreateProcess()而已也是继承参数为TRUE)继承到了我start打开的进程,这也是为什么直到我关闭最后的子进程该端口才关闭


linux下的system好像也有同样的问题,猜测应该也是fork的参数问题


解决方案

(1) 自己写system

(2) 自己写一个代理客户端,客户端一个for循环把所有的socket给关了,可以根据实际情况关闭轮询的最大个数(具体可以搜索linux和windows下socket ID分配策略)

#ifndef _WIN32
for(int i=3;i<128;i++)
{
close(i);
}
#else
for(int i=0;i<1024;i++)
{
closesocket(i);
}
#endif
system(cmd);




原创粉丝点击