views:

588

answers:

2

I have a small application that redirects the stdout/in of an another app (usually command prompt or bash for windows). The problem is that if the connection is interrupted the my process has no idea and it never closes because of this line:

WaitForSingleObject(childProcess.hThread, INFINITE)

I was thinking of having a loop with something like this:

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

}

What functions would I use to accomplish this? For ProcessIsDead I know there is a winapi for getting the exit code but I don't know how to check if the socket is disconnected without calling recv (which i cant do)

+1  A: 

Note: I'm assuming the connected socket is communicating over a network link, because I'm not sure how it would become disconnected if it were a local pipe, except by one process or the other dying.

Use the select() function in the socket API to query the read status of the socket. select() will tell you the socket is "readable" if any of the following is true:

  • If listen has been called and a connection is pending, accept will succeed.
  • Data is available for reading (includes OOB data if SO_OOBINLINE is enabled).
  • Connection has been closed/reset/terminated.

So, if select() says that the socket is readable, it is safe to call recv(), which will give you WSACONNRESET or return 0 bytes if the connection was reset or closed respectively. select() takes a 'timeout' parameter, which you can set to an appropriate time interval or zero if you want to poll the socket state.

Information on the select() function is at http://msdn.microsoft.com/en-us/library/ms740141%28VS.85%29.aspx

swillden
What if data won't always be available? I don't want it to drop the connection if the client is just not executing any commands at the moment.
Chris T
If no data has been received, but the connection is still up, select() will not tell you the socket is readable. If the socket isn't readable, don't call recv(), just keep waiting until it is.
swillden
A: 

case-1: if the peer closed the connection, you'll get 0 bytes when reading tne socket (receive FIN exactly), it's time for you to close the socket.

case-2: you could call close() to close the socket after get enough packets.

case-3: if got interruted when reading or writing the socket, you'll get EINTR or EAGAIN, then please read/write again.

cases 1-3 are independently to the thread because if has any events such as can-read, can-write or errors, system will notify you; so you have chances to handle the events. please try different I/O model.

EffoStaff Effo