CSocket断言错误 ASSERT(pState->m_hSocketWindow != NULL);

CSocket断言错误 ASSERT(pState->m_hSocketWindow != NULL);

flyfish

BOOL CAsyncSocket::AsyncSelect(long lEvent)
{
	ASSERT(m_hSocket != INVALID_SOCKET);


	_AFX_SOCK_THREAD_STATE* pState = _afxSockThreadState;
	ASSERT(pState->m_hSocketWindow != NULL);


	return WSAAsyncSelect(m_hSocket, pState->m_hSocketWindow,
		WM_SOCKET_NOTIFY, lEvent) != SOCKET_ERROR;
}


断言在ASSERT(pState->m_hSocketWindow != NULL);

产生断言的原因
http://support.microsoft.com/kb/140527/en-us
 this problem is due to the sharing of CSocket objects between multiple threads.
也就是在多线程中使用了CSocket对象,主线程中创建socket,在其他线程中关闭socket出现的断言


查找什么地方启动了关闭线程
在主窗口中只调用函数 timeSetEvent
查看MSDN

The timeSetEvent function starts a specified timer event. The multimedia timer runs in its own thread. After the event is activated, it calls the specified callback function or sets or pulses the specified event object The multimedia timer runs in its own thread 

多媒体定时器运行在它自己的线程,也就是这个函数会启动一个线程。

原因找到确定是 多线程中使用了CSocket对象


解决方法
a CAsyncSocket object should be used only in the context of a single thread. If you need to switch the thread that is accessing a SOCKET connection with another thread, then you should use a separate CAsyncSocket object in each thread, and use the Detach and Attach functions to attach the CAsyncSocket object to the SOCKET handle in the thread that is about to use the socket. 


CSocket派生自CAsyncSocket
一个 CAsyncSocket 对象应该只在一个单线程的上下文。如果你想切换到其他的线程中访问SOCKET连接,你应该在每个线程中使用单独的 CAsyncSocket 对象,并使用Detach 和Attach函数将 CAsyncSocket 对象attach到SOCKET handle。


当前拥有这个socket的线程调用Detach方法,socket handle就与当前线程无关
在另一个线程调用 Attach,这个socket handle 就在此线程了
有点类似C++对象和Windows对象之间的关系
如果一个线程要使用其他线程的Windows对象,则必须传递Windows对象句柄,不能传递C++对象指针。


另一种解决方法

仍然是单线程使用CSocket,在主窗口中自定义消息,使用PostMessage向主窗口发送消息



你可能感兴趣的:(CSocket断言错误)