Verwendung von CAsyncSocket führt zu DebugAssertion



  • Hallo zusammen,

    ich möchte in meiner MFC-DLL einen Socket verwenden, um 'von außen' in die DLL eingreifen zu können.

    Ich stelle meine Frage mal vor dem Code (sonst muss man so weit scrollen):
    Wenn ich meine Applikation beende bekomme ich eine Debug-Assertion in der Datei csockcore.cpp im Destruktor von CSocketInterface (Zeile 16, letztes Code-Fragment). Habe das Ganze bis zu dieser Funktion zurückverfolgt:

    CAsyncSocket* PASCAL CAsyncSocket::LookupHandle(SOCKET hSocket, BOOL bDead)
    {
    	CAsyncSocket* pSocket;
    	_AFX_SOCK_THREAD_STATE* pState = _afxSockThreadState;
    	if (!bDead)
    	{
    		pSocket = (CAsyncSocket*)
    			pState->m_pmapSocketHandle->GetValueAt((void*)hSocket);
    		if (pSocket != NULL)
    			return pSocket;
    	}
    	else
    	{
    		pSocket = (CAsyncSocket*)
    			pState->m_pmapDeadSockets->GetValueAt((void*)hSocket);
    		if (pSocket != NULL)
    			return pSocket;
    	}
    	return NULL;
    }
    

    Diese wird aufgerufen, weil das Socket-Handle != INVALID_SOCKET ist und deswegen die Close()-Funktion für den Socket aufgerufen wird. Die Assertion kommt in Zeile 7/8, da pState->m_pmapSocketHandle an dieser Stelle NULL ist.

    Warum ist pState->m_pmapSocketHandle an dieser Stelle NULL??? Sehe leider keinen Fehler, bekomme aber reproduzierbar die Assertion. Hab auch schon ein Beispiel von Microsoft zur Vorlage genommen, da funktioniert das Ganze komischerweise, obwohl dort nicht anders gemacht wird...

    Bisher habe ich folgenden Code:

    class CSocketListener:public CAsyncSocket
    {
       public:
          CSocketListener(void);
          virtual ~CSocketListener(void);
    
          virtual void OnAccept(int nErrorCode);
    
          bool IsClientAvailable(void);
    
       private:
          bool m_bClientAvailable;   // true if a client is available, false otherwise
    };
    
    #include "stdafx.h"
    #include "SocketListener.h"
    
    CSocketListener::CSocketListener(void)
    {
       m_bClientAvailable = false;
    }
    
    CSocketListener::~CSocketListener(void)
    {
    }
    
    bool CSocketListener::IsClientAvailable(void)
    {
       return m_bClientAvailable;
    }
    
    void CSocketListener::OnAccept(int nErrorCode)
    {
       if (0 == nErrorCode)
       {
          m_bClientAvailable = true;
       }
       else
       {
          m_bClientAvailable = false;
       }
    }
    
    class CSocketInterface
    {
       public:
          CSocketInterface);
          ~CSocketInterface(void);
    
          void Reset(void);
    
       private:
          CSocketListener*  m_pListenSocket;        // pointer to listener socket object
          CSocketComm*      m_pCommSocket;          // pointer to communication socket object
          bool              m_bInitialized;         // true if socket interface was reset once, false otherwise
    };
    
    #include "stdafx.h"
    #include "SocketInterface.h"
    #include "SocketListener.h"
    #include "SocketComm.h"
    #include "Einst.h"
    
    CSocketInterface::CSocketInterface()
    {
       m_bInitialized = false;
    }
    
    CSocketInterface::~CSocketInterface(void)
    {
       if (NULL != m_pListenSocket)
       {
          delete m_pListenSocket;
       }
       if (NULL != m_pCommSocket)
       {
          delete m_pCommSocket;
       }
    }
    
    void CSocketInterface::Reset(void)
    {
       if (false == m_bInitialized)
       {
          m_pListenSocket = new CSocketListener();
          VERIFY(m_pListenSocket != NULL);
          // create listener socket
          if (0 == m_pListenSocket->Create(5000))
          {
             // error during creation -> log error
          }
          // setup listening socket for one client
          if (0 == m_pListenSocket->Listen(1))
          {
             // log error
          }
          m_bInitialized = true;
       }
    }
    

    Die Funktion Reset() wird beim Starten der Applikation mehrmals gerufen. Das Objekt der Klasse wird mit CSocketInterface g_SocketInterface; angelegt. Der Aufruf von AfxSocketInit() erfolgt in der InitInstance() der DLL und wird - mit dem Debugger überprüft! - vor dem Aufruf von Reset durchgeführt (gibt auch keinen Fehler zurück).

    Bedanke mich im voraus für jede Hilfe

    P.S.: Hab das gleiche Problem schon auf www.mikrocontroller.net gepostet - bitte nicht vom unterschiedlichen Quellcode verwirren lassen, das dort war mein erster Ansatz - (http://www.mikrocontroller.net/topic/148562#new), dort wurde mir empfohlen das Ganze ohne CAsyncSocket zu versuchen. Ist das der gangbarere Weg? Würde es eigentlich schon ganz gern mit MFC-Klassen realisieren, wenn es sie schon gibt.


Anmelden zum Antworten