RESOLUTION
If your class is derived directly from CAsyncSocket, then replace the
Accept function and modify it so that the error code is not lost.
This can be done by first borrowing the function from the
CAsyncSocket::Accept function found in the MFC source code in the file
SOCKCORE.CPP. Change the function to be implemented as follows:
#if _MFC_VER >= 0x0410 && _MFC_VER <= 0x0420
BOOL CMySocket::Accept(CAsyncSocket& rConnectedSocket,
SOCKADDR* lpSockAddr, int* lpSockAddrLen)
{
ASSERT(rConnectedSocket.m_hSocket == INVALID_SOCKET);
ASSERT(CAsyncSocket::FromHandle(INVALID_SOCKET) == NULL);
CAsyncSocket::AttachHandle(INVALID_SOCKET, &rConnectedSocket);
SOCKET hTemp = accept(m_hSocket, lpSockAddr, lpSockAddrLen);
if (hTemp == INVALID_SOCKET)
{
// <===== STORE THE ERROR CODE RECEIVED FROM THE accept CALL
int nError = WSAGetLastError();
CAsyncSocket::DetachHandle(rConnectedSocket.m_hSocket, FALSE);
// <===== RE-SET THE ERROR CODE THAT WAS SET IN THE accept CALL
WSASetLastError(nError);
rConnectedSocket.m_hSocket = INVALID_SOCKET;
}
else if (CAsyncSocket::FromHandle(INVALID_SOCKET) != NULL)
{
rConnectedSocket.m_hSocket = hTemp;
CAsyncSocket::DetachHandle(INVALID_SOCKET, FALSE);
CAsyncSocket::AttachHandle(hTemp, &rConnectedSocket);
}
return (hTemp != INVALID_SOCKET);
}
#endif // _MFC_VER
If your class is derived from CSocket, then you will have to replace
CAsyncSocket::Accept as well as CSocket::Accept. This is necessary because
CSocket::Accept directly calls CAsyncSocket::Accept. This can be
accomplished by providing your own Accept function, called AcceptFix. It
would be implemented just as the Accept function shown above. For example:
#if _MFC_VER >= 0x0410 && _MFC_VER <= 0x0420
BOOL CMySocket::AcceptFix(CAsyncSocket& rConnectedSocket,
SOCKADDR* lpSockAddr, int* lpSockAddrLen)
{
...
// IMPLEMENTATION IS THE SAME AS THE ONE SHOWN ABOVE
...
return (hTemp != INVALID_SOCKET);
}
#endif // _MFC_VER
Then provide a replacement for CSocket::Accept and modify it to call
AcceptFix instead of CAsyncSocket::Accept. You can borrow the
CSocket::Accept function from SOCKCORE.CPP and modify it as follows:
#if _MFC_VER >= 0x0410 && _MFC_VER <= 0x0420
BOOL CMySocket::Accept(CAsyncSocket& rConnectedSocket,
SOCKADDR* lpSockAddr, int* lpSockAddrLen)
{
if (m_pbBlocking != NULL)
{
WSASetLastError(WSAEINPROGRESS);
return FALSE;
}
// <=============== REPLACE THE FOLLOWING LINE
// while (!CAsyncSocket::Accept(rConnectedSocket, lpSockAddr,...
// <=============== WITH THIS:
while (!AcceptFix(rConnectedSocket, lpSockAddr, lpSockAddrLen))
{
if (GetLastError() == WSAEWOULDBLOCK)
{
if (!PumpMessages(FD_ACCEPT))
return FALSE;
}
else
return FALSE;
}
return TRUE;
}
#endif // _MFC_VER