检查Socket是否已在C ++中关闭

时间:2009-10-19 02:58:09

标签: c++ windows winapi sockets winsock

我有一个小应用程序,重定向另一个应用程序的stdout / in(通常是命令提示符或bash for windows)。问题是如果连接中断,我的进程就不知道了,因为这一行它永远不会关闭:

WaitForSingleObject(childProcess.hThread, INFINITE)

我在考虑使用这样的循环:

while(true)
{
     if(ProcessIsDead(childProcess.hThread))
      // close socket and exit
    if(SocketIsDisocnnected(hSocket))
    // close process and exit

}

我将使用哪些功能来完成此任务?对于ProcessIsDead,我知道有一个winapi用于获取退出代码,但我不知道如何在不调用recv的情况下检查套接字是否已断开连接(我无法做到)

2 个答案:

答案 0 :(得分:4)

注意:我假设连接的套接字是通过网络链接进行通信的,因为我不确定如果它是本地管道,它将如何断开连接,除非是一个进程或另一个进程死亡。

使用套接字API中的select()函数来查询套接字的读取状态。如果满足以下任何条件,select()将告诉您套接字是“可读的”:

  • 如果已调用listen且连接处于挂起状态,则accept将成功。
  • 可以读取数据(如果启用了SO_OOBINLINE,则包括OOB数据)。
  • 连接已关闭/重置/终止。

因此,如果select()表示套接字是可读的,则可以安全地调用recv(),如果连接分别被重置或关闭,它将为您提供WSACONNRESET或返回0字节。 select()接受'timeout'参数,如果要轮询套接字状态,可以将其设置为适当的时间间隔或零。

select()函数的信息位于http://msdn.microsoft.com/en-us/library/ms740141(VS.85).aspx

答案 1 :(得分:0)

case-1:如果对等体关闭了连接,那么在读取套接字时会得到0字节(完全接收FIN),是时候关闭套接字了。

case-2:你可以在获得足够的数据包后调用close()关闭套接字。

案例3:如果在读取或写入套接字时被插入,您将获得EINTR或EAGAIN,然后请再次读/写。

案例1-3独立于线程,因为如果有任何事件,如可读,可写或错误,系统将通知您;所以你有机会处理这些事件。 请尝试不同的I / O模型。

相关问题