From: "Bill Brehm" don't want on 19 Mar 2010 23:13 "I suppose I could do one more thing. If the user presses the button to close the connection before it's connected, I can leave that socket undeleted to wait for the OnConnect and then delete itself inside the OnConnect call. If the user presses the button again to make a new connection, I can create a new socket to handle that request, even if the abandoned one is still not shut down." I tried this and it works perfectly. I still kept the ShutDown() calls in the code to handle the other possible errors. Thanks everyone. "Bill >" <<don't want more spam> wrote in message news:eVJIYToxKHA.3304(a)TK2MSFTNGP06.phx.gbl... > Hector, > > I tried to study and understand your code. Am I right that you are > basically polling the socket until it either connects or the connection > attempt times out? > > Is there an advantage to this over waiting for the OnConnect call to come > with either no error meaning conencted or an error meaning timeout? > > Will the OnConnect call always always always come in? > > It seems a shame that there is no way to abort a connection attempt until > it gives up and gives the timeout. I'm wondering where does the timeout > call come from? If I'm trying to connect to an IP address that doesn't > exist, then I'm guessing that it's the socket code in Windows of my own PC > that is giving me the timeout. If that's the case, I'm surprised that it > can't coordinate that with a deleted object or one where Close was already > called. > > I suppose I could do one more thing. If the user presses the button to > close the connection before it's connected, I can leave that socket > undeleted to wait for the OnConnect and then delete itself inside the > OnConnect call. If the user presses the button again to make a new > connection, I can create a new socket to handle that request, even if the > abandoned one is still not shut down. > > Thanks, > > Bill > > > "Hector Santos" <sant9442(a)nospam.gmail.com> wrote in message > news:O2M8cWlxKHA.5940(a)TK2MSFTNGP02.phx.gbl... >> When I added the yield, I threw out the nCountDown timeout calculation. >> Change it to this: >> >> BOOL CMyClientSocket::WaitConnect(int nTimeout) >> { >> int nSleep = 100; >> DWORD tFinal = GetTickCount()+nTimeout*1000; >> for (;;) { >> if (GetTickCount() > tFinal) { >> SetLastError(WSAETIMEDOUT); >> return FALSE; >> } >> .... >> } >> >> --- >> >> Hector Santos wrote: >> >>> Ok, Bill, >>> >>> What you need to do is do wait on the Connect() like so: >>> >>> if(!m_pClientSocket->Connect(m_toURL, m_toPort)) { >>> int err = GetLastError(); >>> if (err == WSAEWOULDBLOCK) { >>> if (!m_pClientSocket->WaitConnect(5)) { >>> // WaitConnect Error, Show Error >>> err = GetLastError(); >>> m_pClientSocket->Close(); >>> return; >>> } >>> } else { >>> // Connect Error, Show Error >>> err = GetLastError(); >>> m_pClientSocket->Close(); >>> return; >>> } >>> } >>> >>> The WaitConnect() and AsyncYield() functions are a member of your socket >>> subclass >>> >>> BOOL CMyClientSocket::WaitConnect(int nTimeout) >>> { >>> int nSleep = 100; >>> int nCountDown = nTimeout*1000 / nSleep; >>> DWORD t1 = GetTickCount(); >>> for (;;) { >>> nCountDown--; >>> if (nCountDown <= 0) { >>> SetLastError(WSAETIMEDOUT); >>> return FALSE; >>> } >>> fd_set efds; fd_set wfds; >>> FD_ZERO(&efds); FD_ZERO(&wfds); >>> FD_SET(m_hSocket, &efds); >>> FD_SET(m_hSocket, &wfds); >>> struct timeval tv; >>> tv.tv_sec = 0; >>> tv.tv_usec = nSleep*1000; >>> int rc = select(0, NULL, &wfds, &efds, &tv); >>> switch (rc) { >>> case 0: >>> // WE TIMED OUT!! >>> { >>> /* show timeout in some CListBox >>> CString s; >>> s.Format("- wait %d | %d",nCountDown, GetTickCount()-t1); >>> m_dlg->m_log.InsertString(0,s); >>> */ >>> if (AsyncYield(100)) { >>> SetLastError(WSAECONNABORTED); >>> return FALSE; >>> } >>> } >>> break; >>> case SOCKET_ERROR: >>> if (GetLastError() != WSAEWOULDBLOCK) return FALSE; >>> break; >>> default: >>> if (FD_ISSET(m_hSocket,&wfds)) { >>> // WE CONNECTED!! >>> SetLastError(0); >>> return TRUE; >>> } >>> if (FD_ISSET(m_hSocket,&efds)) { >>> // WE FAILED >>> SetLastError(WSAEHOSTUNREACH); >>> return FALSE; >>> } >>> break; >>> } >>> } >>> return FALSE; >>> } >>> >>> BOOL CMyClientSocket::AsyncYield(DWORD nDelay) >>> { >>> DWORD nDone = (GetTickCount() + nDelay); >>> while (nDone > GetTickCount()){ >>> Sleep(75); >>> MSG msg; >>> while (::PeekMessage(&msg,NULL,0,0,PM_REMOVE)){ >>> ::TranslateMessage(&msg); >>> ::DispatchMessage(&msg); >>> } >>> if (m_cancel) { >>> m_cancel = FALSE; >>> return TRUE; >>> } >>> } >>> return FALSE; >>> } >>> >>> My previous message had more details about using the select() socket >>> function. The wait block will use select() which allows you to detect >>> read, write and error events. In this case, you need two events: >>> >>> write event - signals the connection is ready >>> error event - something went wrong >>> >>> That will do the trick for you. >>> >> >> >> >> -- >> HLS > >
First
|
Prev
|
Pages: 1 2 3 4 5 Prev: typedef struct RTTI/Reflection Next: What is the best way to drive (time) animations? |