Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

CAsyncSocket::OnReceive still gets called after closing the socket on system overload

85 views
Skip to first unread message

Sebastian Pötschke

unread,
Jul 17, 2002, 5:34:58 AM7/17/02
to
Hi,

I'm using the MFC class CAsyncSocket in a data relay server application and
I've seen a strange behaviour on heavy system load (90-100% CPU load) and
many connections (>100 CAsyncSocket instances at the same time). The failure
occours, when a server still sends data to the client and the client object
is going to be destroyed. As I know from the documentation at msdn, we have
to force a shutdown to disable send and receive on the socket, before we can
destroy the object. And inside the destructor of the client socket class we
do stuff like this:

CSocketConnector::~CSocketConnector()
{
ShutDown( 2 );

char buffer[1024];
while ( CAsyncSocket::Receive( buffer, 1024 )>0 )
Sleep( 10 );

Close();
}

Note that CSocketConnector is a derived class from CAsyncSocket and
implements a simple socket client.

But this shutdown and close does not work reliable on system overload and
OnReceive callback gets called for already destroyed objects. I wonder if
this problem is related with the internal callback implementation using a
message que. It's still a struggle to use sdk sockets for my, because the
CAsyncSocket interface looks nice and easy, but it does'nt work reliable for
me. Anyway I still hope I do something wrong and you can give me some advice
how to close down a socket.
Any help would be greatly appriciated!

Cheers,
Sebastian.


Ian Semmel

unread,
Jul 17, 2002, 3:06:53 PM7/17/02
to
I think that the destructor might be a bit late in the chain to shut down,
especially if you get errors etc.
Try calling AsyncSelect (0) before Shutdown ()

"Sebastian Pötschke" <poet...@terrasat.de> wrote in message
news:eVOzZUXLCHA.1180@tkmsftngp09...

Sebastian Pötschke

unread,
Jul 18, 2002, 3:35:44 AM7/18/02
to
"Ian Semmel" <ise...@rocketcomp.com.au> wrote in message
news:<OJT06ScLCHA.2548@tkmsftngp08>...

> I think that the destructor might be a bit late in the chain to shut down,
> especially if you get errors etc.
> Try calling AsyncSelect (0) before Shutdown ()
>

Actually calling AsyncSelect(0) before Shutdown() is'nt such a good idea,
because I won't receive any notification callbacks, nor the OnClose()
message indicating a successfull shutdown.

Right, so I did a couple of changes yesterday for testing and one of them
was a quite early shutdown with the following overloaded member function:

BOOL CSocketConnector::ShutDown( int nHow )
{
CAsyncSocket::ShutDown( nHow );

char buffer[1024];
while ( CAsyncSocket::Receive(buffer, 1024)>0 )
Sleep(10);

return TRUE;
}

void CSocketConnector::OnClose(int nErrorCode)
{
CAsyncSocket::OnClose( nErrorCode );
AsyncSelect( 0 );
Close();
}

After the socket connection has been shutdown, I get the OnClose
Notification where I call close() explicitly to destroy the socket handle
inside and avoid further notifications (at least I was assuming that). But I
still can't delete the object after the OnClose() event, because on system
overload (maybe when the windows message que is stuffed with unprocessed
messages) it still receive OnReceive Notifications. Desperately I started to
studied the code of CAsyncSocket and I'm pretty sure that this callback
dispatcher has an unpredictable behaviour in nontrivial situations.

I think I might investigate about some other alternatives, since I can't get
this MFC stuff to run reliable.

Cheers,
Sebastian.

0 new messages