神啊,救救我!!!
有哪位高手能帮帮俺?
在一个多线程的程序中,用一个线程(该线程没有窗口)调用了
CAsyncSocket::AsyncSelect,结果在该函数中出现断言错误。具体是
ASSERT(pState->m_hSocketWindow != NULL);
。经痛苦思索N小时无果。有哪位高人肯出手?兄弟我感激涕淋,呜呜。。。。
问题点数:20、回复次数:3Top
1 楼Congy(少侠)回复于 2001-08-29 20:28:53 得分 0
具体怎么回事,代码贴出来Top
2 楼Once_A_Week(无量罐主)回复于 2001-08-29 20:34:11 得分 0
这个函数是在某个线程中被调用的。
/*------------------------------------------*功能:把需要发送的数据放入发送缓冲区
参数:1、数据的SOCKET包头
2、要发送的数据的地址
返回值:成功则返回该数据的ID值,失败则返回0
\*------------------------------------------*/
extern AFX_MODULE_STATE *g_pState;
ULONG CTransfer::TransData(S_SOCKET_HEAD *pSocketHead, const void *pData)
{
if(m_hSocket != INVALID_SOCKET)
{
if( pData == NULL || pSocketHead->ulLength == 0)
{
return 0;
}
//如果SOCKET包头的字节数 + 准备发送的数据的字节数超过了缓冲区的容量
if(sizeof(S_SOCKET_HEAD) + pSocketHead->ulLength > SEND_BUF_MAX_SIZE)
{
return 0;
}
ULONG len = m_ulSendBufOff + sizeof(S_SOCKET_HEAD) + pSocketHead->ulLength;
//如果发送缓冲区中已有数据的字节数 + SOCKET包头的字节数
//+ 准备发送的正文数据的字节数
//超过了缓冲区的容量
if(len > SEND_BUF_MAX_SIZE)
{
return 0;
}
//先把SOCKET包头放入发送缓冲区
memcpy(m_bySendBuf + m_ulSendBufOff, pSocketHead, sizeof(S_SOCKET_HEAD));
//把正文数据放入发送缓冲区
memcpy(m_bySendBuf + m_ulSendBufOff + sizeof(S_SOCKET_HEAD), pData, pSocketHead->ulLength);
if( m_ulSendBufOff == 0)
{
AsyncSelect( FD_WRITE);//***就是这句了
}
//记录当前发送缓冲区中有效数据的字节数
m_ulSendBufOff += sizeof(S_SOCKET_HEAD) + pSocketHead->ulLength;
//返回数据包的ID值
return pSocketHead->ulID;
}
return 0;
}
Top
3 楼han012(阿毛)回复于 2001-08-29 21:53:27 得分 20
你的错误源于在多个线程之间共享(sharing)一个CAsyncSocket类,这是一个经典的使用CAsyncSocket(CSocket)的错误.
一个CAsyncSocket(CSocket)应该只在一个线程上下文(context)中使用.因为被CAsyncSocket封装的SOCKET handle被存储在"per-thread handle map"中.另外用于Socket消息通知的隐藏
窗口m_hSocketWindow也被存储在"per-thread handle map"中
如果CAsyncSocket object在另一个线程中create,Socket消息通知窗口m_hSocketWindow也在另一个线程中create(即m_hSocketWindow属于另一个线程). 所以在当前线程中使用这个CAsyncSocket object时,在当前线程中m_hSocketWindow必是NULL.所以ASSERT错误出现
解决方法:
如果你希望在不同的线程中共享一个SOCKET,你必须在每一个线程中使用各自的CAsyncSocket object(即每个线程中拥有自己的m_hSocketWindow),通过使用Detach(),Attach()函数使这个SOCKET attach到一个线程的CAsyncSocket object上(这个线程即将使用这个SOCKET ).
1. Use Detach() to detach the CAsyncSocket object from the SOCKET handle in the thread that is currently using the CAsyncSocket object
2. Use Attach() to attach a different CAsyncSocket object to the SOCKET handle while in the context of the MFC UI thread in which you wish to begin accessing the SOCKET connection.
... ...
总之一个CAsyncSocket object 不能在多个线程中共享. 但SOCKET handle 可以共享.
具体的说明你可以查阅MSDN.
Top




