user1205577
user1205577

Reputation: 2450

Interrupt a receiving socket

I have a WinSock mySocket that receives in a loop like so:

while(keepGoing){
    FD_SET fsd;
    FD_ZERO(&fds);
    FD_SET(mySocket, &fds);

    int result = select(1+mySocket, &fds, (fd_set *)0, (fd_set *)0, &timeout);
    if(result>0 && FD_ISSET(mySocket, &fds){
        result = recvfrom(mySocket, buff, NUM_BYTES, (struct sockaddr *)&add, &length);
        // do stuff       
    }
}

If I want to stop receiving I can set keepGoing to false, but the socket may still be waiting for timeout before it sees that keepGoing has changed.

Assuming that we do not want to change the value of the timeout, is there a reliable way to tell the socket to stop receiving without waiting for the timeout to occur?

Upvotes: 3

Views: 1280

Answers (1)

jxh
jxh

Reputation: 70372

You can raise a benign signal and check the keepGoing flag when the errno is EINTR. Or, you can create a pipe and add the read end to your select set. Close the write end after setting the keepGoing flag.

int quitfds[2];
pipe(quitfds);

    //...
    FD_SET(quitfds[0], &fds);
    //...

    if (FD_ISSET(quitfds[0], &fds)) {
        close(quitfds[0]);
        continue;
    }

Edit: Adam points out that I missed the Winsock reference in the question. You can use a socketpair instead of a pipe. It doesn't seem to be implemented on Windows, but I found a workaround here. Ben points out that WSAEventSelect allows mixing of different event objects. Thanks to both.

Upvotes: 1

Related Questions