Safely cancel a connect call
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.
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).
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
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!
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement
Recommended Tutorials
Advertisement