From: "Bill Brehm" don't want on
"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
>
>