From: "Bill Brehm" don't want on
I have a problem with CAsynsocket. I can connect to a remote socket. When I
want to close the connection, I just delete the socket object (which closes
the connection) and have no problems.

But if I've started to connect to a remote socket that doesn't exist (or
doesn't accept), and I delete the local socket object while waiting for the
connection, I sometimes get an assert in CAsyncSocket::DoCallBack(). See
below. Actually, it's not in the middle of an Accept call because I test
with an address and port that I know doesn't exist.

Any idea how I should be doing this so as not to crash my program?

Thanks,

Bill


void PASCAL CAsyncSocket::DoCallBack(WPARAM wParam, LPARAM lParam)
{
if (wParam == 0 && lParam == 0)
return;

// Has the socket be closed?
CAsyncSocket* pSocket = CAsyncSocket::LookupHandle((SOCKET)wParam, TRUE);

// If yes ignore message
if (pSocket != NULL)
return;

pSocket = CAsyncSocket::LookupHandle((SOCKET)wParam, FALSE);
if (pSocket == NULL)
{
// Must be in the middle of an Accept call
pSocket = CAsyncSocket::LookupHandle(INVALID_SOCKET, FALSE);
ASSERT(pSocket != NULL);
<-------------------------------------------------asserts here sometimes but
not always.
pSocket->m_hSocket = (SOCKET)wParam;
CAsyncSocket::DetachHandle(INVALID_SOCKET, FALSE);
CAsyncSocket::AttachHandle(pSocket->m_hSocket, pSocket, FALSE);
}


From: "Bill" don't want more on
Did I ask this in the right newsgroup? (Just not sure if there is a more
appropriate palce to ask this.) Tnx.

"Bill Brehm" <don't want spam> wrote in message
news:ujK0YBavKHA.5980(a)TK2MSFTNGP05.phx.gbl...
>I have a problem with CAsynsocket. I can connect to a remote socket. When I
>want to close the connection, I just delete the socket object (which closes
>the connection) and have no problems.
>
> But if I've started to connect to a remote socket that doesn't exist (or
> doesn't accept), and I delete the local socket object while waiting for
> the connection, I sometimes get an assert in CAsyncSocket::DoCallBack().
> See below. Actually, it's not in the middle of an Accept call because I
> test with an address and port that I know doesn't exist.
>
> Any idea how I should be doing this so as not to crash my program?
>
> Thanks,
>
> Bill
>
>
> void PASCAL CAsyncSocket::DoCallBack(WPARAM wParam, LPARAM lParam)
> {
> if (wParam == 0 && lParam == 0)
> return;
>
> // Has the socket be closed?
> CAsyncSocket* pSocket = CAsyncSocket::LookupHandle((SOCKET)wParam, TRUE);
>
> // If yes ignore message
> if (pSocket != NULL)
> return;
>
> pSocket = CAsyncSocket::LookupHandle((SOCKET)wParam, FALSE);
> if (pSocket == NULL)
> {
> // Must be in the middle of an Accept call
> pSocket = CAsyncSocket::LookupHandle(INVALID_SOCKET, FALSE);
> ASSERT(pSocket != NULL);
> <-------------------------------------------------asserts here sometimes
> but not always.
> pSocket->m_hSocket = (SOCKET)wParam;
> CAsyncSocket::DetachHandle(INVALID_SOCKET, FALSE);
> CAsyncSocket::AttachHandle(pSocket->m_hSocket, pSocket, FALSE);
> }
>
>


From: Geoff on
On Wed, 10 Mar 2010 10:42:21 +0800, "Bill" <<don't want more spam>>
wrote:

>Did I ask this in the right newsgroup? (Just not sure if there is a more
>appropriate palce to ask this.) Tnx.
>

Dr. Joe usually has a lot to say about callbacks and about
CAsyncSocket but he must be busy polishing his new MVP award.

I am not sure why you think you need to poll the handle. What you
should be doing is either closing it with CAsyncSocket::Close when you
are done with your session on your end or else responding to
CAsyncSocket::OnClose and doing any cleanup if it is closed from the
other end.
From: Stephen Myers on
Bill Brehm wrote:
> I have a problem with CAsynsocket. I can connect to a remote socket. When I
> want to close the connection, I just delete the socket object (which closes
> the connection) and have no problems.
>
> But if I've started to connect to a remote socket that doesn't exist (or
> doesn't accept), and I delete the local socket object while waiting for the
> connection, I sometimes get an assert in CAsyncSocket::DoCallBack(). See
> below. Actually, it's not in the middle of an Accept call because I test
> with an address and port that I know doesn't exist.
>
> Any idea how I should be doing this so as not to crash my program?
>
> Thanks,
>
> Bill
>
>
> void PASCAL CAsyncSocket::DoCallBack(WPARAM wParam, LPARAM lParam)
> {
> if (wParam == 0 && lParam == 0)
> return;
>
> // Has the socket be closed?
> CAsyncSocket* pSocket = CAsyncSocket::LookupHandle((SOCKET)wParam, TRUE);
>
> // If yes ignore message
> if (pSocket != NULL)
> return;
>
> pSocket = CAsyncSocket::LookupHandle((SOCKET)wParam, FALSE);
> if (pSocket == NULL)
> {
> // Must be in the middle of an Accept call
> pSocket = CAsyncSocket::LookupHandle(INVALID_SOCKET, FALSE);
> ASSERT(pSocket != NULL);
> <-------------------------------------------------asserts here sometimes but
> not always.
> pSocket->m_hSocket = (SOCKET)wParam;
> CAsyncSocket::DetachHandle(INVALID_SOCKET, FALSE);
> CAsyncSocket::AttachHandle(pSocket->m_hSocket, pSocket, FALSE);
> }
>
>

My guess is that the Connect handling is causing the problem. Connect()
will return immediately. You will then get OnConnect(), with or without
an error. The timeout varies, but I would expect it to be on the order
of 5 seconds. Once OnConnect has been called you should be able to
close the socket.

HTH
Steve
From: "Bill" don't want more on
Geoff,

The code I showed was from MFC, not from me. So I'm not doing any polling. I
pasted that in to show where the ASSERT is coming from.

My code is deleting the socket object, which according to my comment will
also close the connection.

delete m_pClientSocket; // this will also close the connection
m_pClientSocket = NULL;

The help says "The socket object's destructor calls Close for you." so I
guess that's why I think I only need to delete the object.

I do respond to OnClose().

I just put some breakpoints at OnClose(), OnConnect() and OnAccept().
Neither is being hit when I try to connect to a non-existent IP and port,
whether the ASSERT happens or not. The call stack looks like below, which
only tells me it's not coming directly from a call in my code. It looks like
the systems was preparing to do a callback.

Oh, I see if I am patient, I will get a call to OnConnect() with an 10060
(WSAETIMEDOUT) error about 20 seconds after initiating the conenct. I do
have to handle that differently.

I was thinking that maybe the timeout callback was coming in just as I was
deleting the socket object. But it doesn't seem likely as I can get the
ASSERT long before the 20 second timeout occurs. Any way I can determine
what the callback would have been had it not crashed? wParam = 1764 and
lParam = 657850384 or hex 27360010.

Bill

CAsyncSocket::DoCallBack(unsigned int 1764, long 657850384) line 513 + 25
bytes
CSocket::ProcessAuxQueue() line 823
CSocketWnd::OnSocketNotify(unsigned int 1764, long 657850384) line 1127
CWnd::OnWndMsg(unsigned int 883, unsigned int 1764, long 657850384, long *
0x0012f560) line 1815 + 17 bytes
CWnd::WindowProc(unsigned int 883, unsigned int 1764, long 657850384) line
1585 + 30 bytes
AfxCallWndProc(CWnd * 0x009f5798 {CSocketWnd hWnd=0x000110d6}, HWND__ *
0x000110d6, unsigned int 883, unsigned int 1764, long 657850384) line 215 +
26 bytes
AfxWndProc(HWND__ * 0x000110d6, unsigned int 883, unsigned int 1764, long
657850384) line 368
AfxWndProcBase(HWND__ * 0x000110d6, unsigned int 883, unsigned int 1764,
long 657850384) line 220 + 21 bytes
USER32! 7e418734()
USER32! 7e418816()
USER32! 7e4189cd()
USER32! 7e4196c7()
CWinThread::PumpMessage() line 853
CWnd::RunModalLoop(unsigned long 4) line 3478 + 19 bytes
CDialog::DoModal() line 539 + 12 bytes
CSocketApp::InitInstance() line 65 + 11 bytes
AfxWinMain(HINSTANCE__ * 0x00400000, HINSTANCE__ * 0x00000000, char *
0x00141f1e, int 1) line 39 + 11 bytes
SOCKET! 0040dec8() line 30
WinMainCRTStartup() line 330 + 54 bytes


"Geoff" <geoff(a)invalid.invalid> wrote in message
news:e6cep51nscc07242lblsa06lublh53030h(a)4ax.com...
> On Wed, 10 Mar 2010 10:42:21 +0800, "Bill" <<don't want more spam>>
> wrote:
>
>>Did I ask this in the right newsgroup? (Just not sure if there is a more
>>appropriate palce to ask this.) Tnx.
>>
>
> Dr. Joe usually has a lot to say about callbacks and about
> CAsyncSocket but he must be busy polishing his new MVP award.
>
> I am not sure why you think you need to poll the handle. What you
> should be doing is either closing it with CAsyncSocket::Close when you
> are done with your session on your end or else responding to
> CAsyncSocket::OnClose and doing any cleanup if it is closed from the
> other end.