zoukker
asked on
Socket Problem in Mutli-threaded Application *URGENT*
Hi guys,
I have a problem working with CSocket in a mutli-threaded application. Basically, I created my sockets in the main application, then passed the SOCKET handles to the my worker thread via my dialog class object (since CSocket objects asserts when they're passed directly to another thread).
After using the sockets in my worker thread, I want to be able to transfer the control of the sockets back to my main user interface (UI) thread. My problem lies in that after the worker thread ends and transfers the sockets back to my original UI thread, they're unable to work. ie: my sockets don't work on an OnReceive() notification anymore.
//------------- code begins --------
// defined elsewhere
HANDLE m_hSocket, m_hTCPSocket;
CSocket m_pSocket, m_pTCPSocket;
CClientDialogDlg::StartThr ead()
{
:
:
// my sockets are detached at this point
m_hSocket = m_pSocket->Detach();
m_hTCPSocket = m_pTCPSocket->Detach();
AfxBeginThread(WorkerThrea d, this);
}
UINT WorkerThread( LPVOID pParam )
{
// The follow code is a workaround the VC++ 6.0 bug (see article Q193101)
#ifndef _AFXDLL
#define _AFX_SOCK_THREAD_STATE AFX_MODULE_THREAD_STATE
#define _afxSockThreadState AfxGetModuleThreadState()
_AFX_SOCK_THREAD_STATE* pState = _afxSockThreadState;
if (pState->m_pmapSocketHandl e == NULL)
pState->m_pmapSocketHandle = new CMapPtrToPtr;
if (pState->m_pmapDeadSockets == NULL)
pState->m_pmapDeadSockets = new CMapPtrToPtr;
if (pState->m_plistSocketNoti fications == NULL)
pState->m_plistSocketNotif ications = new CPtrList;
#endif
// end workaround
CClientDialogDlg* dlg = (CClientDialogDlg*) pParam;
CSocket Socket;
CSocket TCPSocket;
Socket.Attach(dlg->m_hSock et);
TCPSocket.Attach(dlg->m_hT CPSocket);
:
// Socket, TCPSocket operations
:
// WM_ATTACH_SOCKET message mapped to CClientDialogDlg::AttachSo cket()
dlg->SendMessage(WM_ATTACH _SOCKET);
return 0;
}
void CClientDialogDlg::AttachSo cket()
{
m_pSocket->Attach( m_hSocket );
m_pTCPSocket->Attach( m_hMmSocket );
// after this point my sockets cannot work anymore on the UI thread
}
I have a problem working with CSocket in a mutli-threaded application. Basically, I created my sockets in the main application, then passed the SOCKET handles to the my worker thread via my dialog class object (since CSocket objects asserts when they're passed directly to another thread).
After using the sockets in my worker thread, I want to be able to transfer the control of the sockets back to my main user interface (UI) thread. My problem lies in that after the worker thread ends and transfers the sockets back to my original UI thread, they're unable to work. ie: my sockets don't work on an OnReceive() notification anymore.
//------------- code begins --------
// defined elsewhere
HANDLE m_hSocket, m_hTCPSocket;
CSocket m_pSocket, m_pTCPSocket;
CClientDialogDlg::StartThr
{
:
:
// my sockets are detached at this point
m_hSocket = m_pSocket->Detach();
m_hTCPSocket = m_pTCPSocket->Detach();
AfxBeginThread(WorkerThrea
}
UINT WorkerThread( LPVOID pParam )
{
// The follow code is a workaround the VC++ 6.0 bug (see article Q193101)
#ifndef _AFXDLL
#define _AFX_SOCK_THREAD_STATE AFX_MODULE_THREAD_STATE
#define _afxSockThreadState AfxGetModuleThreadState()
_AFX_SOCK_THREAD_STATE* pState = _afxSockThreadState;
if (pState->m_pmapSocketHandl
pState->m_pmapSocketHandle
if (pState->m_pmapDeadSockets
pState->m_pmapDeadSockets = new CMapPtrToPtr;
if (pState->m_plistSocketNoti
pState->m_plistSocketNotif
#endif
// end workaround
CClientDialogDlg* dlg = (CClientDialogDlg*) pParam;
CSocket Socket;
CSocket TCPSocket;
Socket.Attach(dlg->m_hSock
TCPSocket.Attach(dlg->m_hT
:
// Socket, TCPSocket operations
:
// WM_ATTACH_SOCKET message mapped to CClientDialogDlg::AttachSo
dlg->SendMessage(WM_ATTACH
return 0;
}
void CClientDialogDlg::AttachSo
{
m_pSocket->Attach( m_hSocket );
m_pTCPSocket->Attach( m_hMmSocket );
// after this point my sockets cannot work anymore on the UI thread
}
ASKER
Opps, I'm terribly sorry, especially to you, manlore! I omitted the Detach() parts from my question, but not my original code...
my thread code is as follows.. but it still fails as before...
UINT WorkerThread( LPVOID pParam )
{
// The follow code is a workaround the VC++ 6.0 bug (see article Q193101)
#ifndef _AFXDLL
#define _AFX_SOCK_THREAD_STATE AFX_MODULE_THREAD_STATE
#define _afxSockThreadState AfxGetModuleThreadState()
_AFX_SOCK_THREAD_STATE* pState = _afxSockThreadState;
if (pState->m_pmapSocketHandl e == NULL)
pState->m_pmapSocketHandle = new CMapPtrToPtr;
if (pState->m_pmapDeadSockets == NULL)
pState->m_pmapDeadSockets = new CMapPtrToPtr;
if (pState->m_plistSocketNoti fications == NULL)
pState->m_plistSocketNotif ications = new CPtrList;
#endif
// end workaround
CClientDialogDlg* dlg = (CClientDialogDlg*) pParam;
CSocket Socket;
CSocket TCPSocket;
Socket.Attach(dlg->m_hSock et);
TCPSocket.Attach(dlg->m_hT CPSocket);
:
// Socket, TCPSocket operations
:
// detach portions
Socket.Detatch()
TCPSocket.Detatch()
// WM_ATTACH_SOCKET message mapped to
CClientDialogDlg::AttachSo cket()
dlg->SendMessage(WM_ATTACH _SOCKET);
return 0;
}
my thread code is as follows.. but it still fails as before...
UINT WorkerThread( LPVOID pParam )
{
// The follow code is a workaround the VC++ 6.0 bug (see article Q193101)
#ifndef _AFXDLL
#define _AFX_SOCK_THREAD_STATE AFX_MODULE_THREAD_STATE
#define _afxSockThreadState AfxGetModuleThreadState()
_AFX_SOCK_THREAD_STATE* pState = _afxSockThreadState;
if (pState->m_pmapSocketHandl
pState->m_pmapSocketHandle
if (pState->m_pmapDeadSockets
pState->m_pmapDeadSockets = new CMapPtrToPtr;
if (pState->m_plistSocketNoti
pState->m_plistSocketNotif
#endif
// end workaround
CClientDialogDlg* dlg = (CClientDialogDlg*) pParam;
CSocket Socket;
CSocket TCPSocket;
Socket.Attach(dlg->m_hSock
TCPSocket.Attach(dlg->m_hT
:
// Socket, TCPSocket operations
:
// detach portions
Socket.Detatch()
TCPSocket.Detatch()
// WM_ATTACH_SOCKET message mapped to
CClientDialogDlg::AttachSo
dlg->SendMessage(WM_ATTACH
return 0;
}
It might be helpful to know what you are doing with your sockets in the workerthread and the UI-thread. Tried to reproduce your problem but the
following scenario works:
UI-thread: Listen for incoming connection, accept it, start workerthread
and detach
Worker: Attach, receive, and detach.
UI-thread:Attach and receive.
following scenario works:
UI-thread: Listen for incoming connection, accept it, start workerthread
and detach
Worker: Attach, receive, and detach.
UI-thread:Attach and receive.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
you should only use CSockets inside a CWinThread type thread
// Socket, TCPSocket operations
:
// Detach sockets
Socket.Detach();
TCPSocket.Detach();
// WM_ATTACH_SOCKET message mapped to CClientDialogDlg::AttachSo
dlg->SendMessage(WM_ATTACH
return 0;
}