请教,我利用MFC的CAsynSocket,派生了服务器端的侦听socket,以及远端客户端的连接来的socket,我在服务器端管理若干个客户端socket,问题是,我在关闭这些socket的时候,程序发生错误,可能原因是正在收发数据。我想问的是怎么正确关闭已经生成的socket对象?程序代码如下:其中,调用pSocket->Close()的时候发生错误。                 //清理客户端连接socket
POSITION pos = this->m_ClientInfoMap.GetStartPosition();
CNewSocket *pSocket = NULL;
CString strIPAddr;
for(pos;pos != NULL;)
{
                             ////////////
 this->m_ClientInfoMap.GetNextAssoc(pos,strIPAddr,(void *&)pSocket);
 if(pSocket)
 {
 pSocket->ShutDown(2);
 //..........................
 pSocket->Close();
 delete pSocket;
 pSocket = NULL;
 }
}
this->m_ClientInfoMap.RemoveAll();
//
//删除侦听socket

if(m_pLisener->m_hSocket != INVALID_SOCKET)
{
//
m_pLisener->ShutDown(2);
int nError = ::WSAGetLastError();
//..............................................
m_pLisener->Close();
delete m_pLisener;
}

解决方案 »

  1.   

    怎么没有人帮帮我啊?也许我说的不是很清楚。我是在从CWinTread派生的类中使用CAsyncSocket的。我在close前调用pSocket->AsyncSelect(0),发生了同样的错误,在堆栈中追踪,发现是一个断言错误,ASSERT(pState->m_hSocketWindow != NULL),这到底是怎么回事?
      

  2.   

    以前遇到过。你的socket是new出来的吧,在关闭之前加一句pSocket->m_hSocket = INVILID_SOCKET还不行再加一句CloseSocket(pSocket->m_hSocket)
      

  3.   

    恢复楼上,用你所说的,程序是走了,但是还是出错:Call Stack 看到如下:(说明,我关闭socket的时候,还有大量数据在收发)
    CAsyncSocket::DoCallBack(unsigned int 525812, long 1) line 527 + 12 bytes
    CSocket::ProcessAuxQueue() line 822
    CSocketWnd::OnSocketNotify(unsigned int 525812, long 1) line 1126
    CWnd::OnWndMsg(unsigned int 883, unsigned int 525812, long 1, long * 0x0012fd10) line 1815 + 17 bytes
    CWnd::WindowProc(unsigned int 883, unsigned int 525812, long 1) line 1585 + 30 bytes
    AfxCallWndProc(CWnd * 0x0149be30 {CSocketWnd hWnd=0x000b02da}, HWND__ * 0x000b02da, unsigned int 883, unsigned int 525812, long 1) line 215 + 26 bytes
    AfxWndProc(HWND__ * 0x000b02da, unsigned int 883, unsigned int 525812, long 1) line 368
    AfxWndProcBase(HWND__ * 0x000b02da, unsigned int 883, unsigned int 525812, long 1) line 220 + 21 bytes
    USER32! 77e2158f()
    USER32! 77e21dc9()
    USER32! 77e07ed6()
    CWinThread::Run() line 480 + 11 bytes
    CWinApp::Run() line 400
    AfxWinMain(HINSTANCE__ * 0x00400000, HINSTANCE__ * 0x00000000, char * 0x001336f1, int 1) line 49 + 11 bytes
    WinMain(HINSTANCE__ * 0x00400000, HINSTANCE__ * 0x00000000, char * 0x001336f1, int 1) line 30
    WinMainCRTStartup() line 330 + 54 bytes
    KERNEL32! 77e88989()
      

  4.   

    it seems like you create (CSocket::Create()) in one thread and use it (Receive()) in another. MFC CSocket uses internal window for blocking+sock notifications etc. The window hwnd is stored in _AFX_SOCK_THREAD_STATE that is local to each thread (ref. thread states in MSDN TN058).
    So your CSocket hwnd is stored in the thread where you invoked Create, and CSocket looks it up in another where you invoke Receive. That is the reason for ASSERT(pState->m_hSocketWindow != NULL);
      

  5.   

    楼上,你好!我的soket对象是在一个线程里(该线程是从CWinThread派生的,之所以这么做,我是想用该线程的Windows消息队列,在其他线程中通过PostThreadMessage向该线程发消息)创建和侦听并收发数据的,删除socket对象也是在同一个线程中(如同上面程序代码)。在这种情况下,是不是不能用CAsyncSocket?如果能用,怎么处理。另外,目前,虽然能够运行上边的程序,也就是单步运行的时候不出错,但是,当 CWinThread线程退出时,会发生错误。从堆栈看,是socket还没有真正退出,正在接收数据(我关闭线程时,还有大量数据向socket发送)。
      

  6.   

    干脆不要用pSocket->Close()
    直接用CloseSocket(pSocket->m_hSocket)