Safely cancel a connect call

Started by
5 comments, last by nevernomore 18 years, 8 months ago
Hello, friends! I have a little question. It concerns both Linux and Winsock, I'll take answers for either one :). I launch a thread, that will try to connect to an address given by the user. At this point, I would like to display a dialog box with a cancel button from the main thread. The cancel-button should, of course, cancel the call to connect. My problem is, I haven't really figured out a good way to do that. Reading the man pages, I thought of making the socket temporarily non-blocking, in which case the socket won't block the connect, and I can wait for the connection using select with a timeout repeatedly (checking for a variable flagging cancel between select calls). Problem is, I don't know if this is a good or bad idea, and I can't figure out, reading the man pages, how to make a non-blocking socket block again.
Advertisement

You can do this by making the socket non-blocking as you say. Call connect until you get a ISCONN error, or until your user cancels, or a decided timeout is reached. During the time you are waiting to connect, ignore WOULDBLOCK, INPROGRESS, and ALREADY errors.
The following code seems to work for me to switch a socket between blocking modes. (p_block is true if the socket should block). I think I heard that some systems don't support changing the blocking status back after you have already changed it... can't remember.
#ifdef _WIN32	unsigned long t_argp = (p_block ? 0 : 1);	if (ioctlsocket(m_socketHandle, FIONBIO, &t_argp) == SOCKET_ERROR) {		log error...	}#else	if (fcntl(m_socketHandle, F_SETFL, (p_block ? O_SYNC : O_NONBLOCK)) == -1) {		log error...	}#endif
Thank you very much, I will try what you suggested, and come back If I run into problems!
PLEASE don't poll by calling connect repeatedly. You have notification mechanisms like select() (and other things on windows). Use them.

As far as "cancelling" a connect, you have to close the socket. It will be connected otherwise (provided the remote side is listening).
I got this working using select, just one little question left. When the user cancels, is it a good idea to call shutdown() before calling close()/closesocket() on the socket that is in progress connecting (but has not yet completed), or is it simply redundant?
Im not sure if your aware of this FAQ, but I found it to be a very useful resource: Sockets FAQ


Also, this is the code I use to safely shutdown my client socket connection

// DESC - shuts down the current winsock conenction and unloads winsock DLLvoid Stop(void){    // send remaining sockets    DEBUG("\nshutdown()...");		    // shutdown - will call FD_CLOSE if currently conected (async socket)    // see winsock FAQ    shutdown(m_socket, SD_SEND );    DEBUG("[OK]\n");		    int bytesRecv = SOCKET_ERROR;    char recvbuf[32];		    DEBUG("Eating up receive buffer...");		    // possible can return -1 (basically no connection) so    // perform greater than comparison    while( bytesRecv > 0 )     {        // eat what's left in the socket buffer        bytesRecv = recv( m_socket, recvbuf, 32, 0 );	DEBUG("\nate: %d bytes", bytesRecv);    }    DEBUG("[OK]\n");		    // close socket    DEBUG("closesocket()...");    closesocket(m_socket);    DEBUG("[OK]\n");		    // close winsock DLL    DEBUG("WSACleanup()...");    WSACleanup();    DEBUG("[OK]\n");		    CONSOLE("\n[Client stopped]\n");}

Boo ya grandma.. boo ya!
There is no need to call shutdown in this case. close the socket and get on with life.

This topic is closed to new replies.

Advertisement