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.
"Sebastian Pötschke" <poet...@terrasat.de> wrote in message
news:eVOzZUXLCHA.1180@tkmsftngp09...
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.