1. 程式人生 > >關於mfc下多執行緒socket出錯

關於mfc下多執行緒socket出錯

問?:

我用CSocket寫通訊程式,但執行到下面的函式時總出錯,是什麼原因?
是多執行緒通訊,每個執行緒建立了一個套接字:CMySocket *m_pClientSocket = New CMySocket;
然後在OnSendSocket函式中呼叫:m_pClientSocket->Send(str,len);
如果訊息很少,或者中間有Sleep,則沒有錯誤,否則必然出現ASSERT(pState->m_hSocketWindow != NULL);的錯誤。
聽說
1 是一個Bug,我用VC 5.0也打了sp5,
2 同一個套接字不能在不同的執行緒傳輸,但是我每一個執行緒建立了一個單獨的套接字
3 沒有呼叫AfxSockInit(),但是我在每個執行緒的初始化中都呼叫了這個函式。
現在實在沒有辦法解決,請大家幫忙,感謝!


下面的函式是 .../MFC/SRC/SOCKCORE.CPP 裡的函式。
BOOL CSocket::PumpMessages(UINT uStopFlag)
{
// The same socket better not be blocking in more than one place.
ASSERT(m_pbBlocking == NULL);

_AFX_SOCK_THREAD_STATE* pState = _afxSockThreadState;

ASSERT(pState->m_hSocketWindow != NULL); //這句出錯這句出錯這句出錯這句出錯

BOOL bBlocking = TRUE;
m_pbBlocking = &bBlocking;

答:(from microsoft)

Most frequently, this problem is due to the sharing of CSocket objects between multiple threads.

A CSocket object should be used only in the context of a single thread because the SOCKET handle encapsulated by a CAsyncSocket object is stored in a per-thread handle map. (CSocket is derived from CAsyncSocket.) Other information is stored on a per-thread basis, including a hidden notification window that MFC uses for socket notifications.

The assertion failure line, which can be found in Sockcore.cpp in the /Msvc20/Mfc/Src directory, is:

   ASSERT(pThreadState->m_hSocketWindow != NULL);

This assertion failure occurs because the CSocket object was either created or accepted in the context of another thread. The socket notification window was created in a different thread, and the m_hSocketWindow for the current thread is NULL, thus the assertion failure.