CSocket and threads
John Addis -- jaddis@erols.com Saturday, March 30, 1996 Environment: NT 3.51, VC++ 4.0, _AFXDLL, sockcore.cpp line 709 '95, VC++ 4.1, _AFXDLL, sockcore.cpp line 694 Here's the scenario; typical client/server development. When a client connects I want to create a new thread (and a socket to go along with it) to service the client. The accept() call works okay and MFC creates a *new* CSocketWnd to go along with my CSocket object. The _AFX_SOCK_THREAD_STATE for the new thread *is* different from that of the main thread. The m_hSocketWindow members are also different. However... when notifications come in for the socket in the _child thread_ they go to the CSocketWnd for the socket in the _main thread_. (I discovered this by tracing through in the debugger.) When CAsyncSocket::DoCallBack() uses LookupHandle() to map the hSocket (wParam) to a CSocket* it fails -- it is looking in the map for the wrong thread. Anybody have any ideas on how to fix this? Is it simply not possible to use CSocket in this manner? Abbreviated code follows: ------------------------ void CTestSock::OnAccept(int n) { CSocket::OnAccept(n); ::AfxBeginThread( ::ThreadProc, this ); } UINT ThreadProc(LPVOID pParm) { CSocket* pListener = (CSocket*)pParm; CServerSock sock; pListener->Accept( sock ); BOOL bMore = TRUE; while( bMore ) { if (::WaitMessage()) { // process the message } } return 0; } tia (even if your answer sucks, Mike) -- John Addis Master of Time and Space jaddis@erols.com C++, MFC, Win32, Win95, TCP/IP "Invalid or missing REALITY.COM Universe halted."
Dean McCrory -- deanm@microsoft.com Sunday, March 31, 1996 You can't pass CSocket* between threads like that (as you have discovered...). Instead of passing the CSocket*, you should instead pass the handle to the socket to the other thread. >void CTestSock::OnAccept(int n) >{ > CSocket::OnAccept(n); > ::AfxBeginThread( ::ThreadProc, m_hSocket ); >} >UINT ThreadProc(LPVOID pParm) >{ CAsyncSocket listener; listener.Attach((SOCKET)pParam); CServerSock sock; listener.Accept(sock); listener.Detach(); .... // Dean McCrory // Team Jakarta >---------- >From: John Addis[SMTP:jaddis@erols.com] >Sent: Friday, March 29, 1996 10:04 PM >To: mfc-l@netcom.com >Subject: CSocket and threads > >Environment: > NT 3.51, VC++ 4.0, _AFXDLL, sockcore.cpp line 709 > '95, VC++ 4.1, _AFXDLL, sockcore.cpp line 694 > >Here's the scenario; typical client/server development. When a client >connects I want to create a new thread (and a socket to go along with >it) to service the client. > >The accept() call works okay and MFC creates a *new* CSocketWnd to go >along with my CSocket object. The _AFX_SOCK_THREAD_STATE for the new >thread *is* different from that of the main thread. The >m_hSocketWindow >members are also different. > >However... when notifications come in for the socket in the _child >thread_ they go to the CSocketWnd for the socket in the _main thread_. >(I discovered this by tracing through in the debugger.) When >CAsyncSocket::DoCallBack() uses LookupHandle() to map the hSocket >(wParam) to a CSocket* it fails -- it is looking in the map for the >wrong thread. > >Anybody have any ideas on how to fix this? Is it simply not possible to > >use CSocket in this manner? > >Abbreviated code follows: >------------------------ >void CTestSock::OnAccept(int n) >{ > CSocket::OnAccept(n); > ::AfxBeginThread( ::ThreadProc, this ); >} >UINT ThreadProc(LPVOID pParm) >{ > CSocket* pListener = (CSocket*)pParm; > CServerSock sock; > pListener->Accept( sock ); > > BOOL bMore = TRUE; > while( bMore ) > { > if (::WaitMessage()) > { > // process the message > } > } > return 0; >} > >tia (even if your answer sucks, Mike) > >-- >John Addis Master of Time and Space >jaddis@erols.com C++, MFC, Win32, Win95, TCP/IP >"Invalid or missing REALITY.COM Universe halted." > >
Les -- Les.Hill@FMR.Com Monday, April 01, 1996 [Mini-digest: 2 responses] To use CAsyncSocket here is what I have done in the past (I image CSocket would be similar): use ::accept() to get a raw SOCKET create your new thread passing the raw socket use Attach to make the connection from the raw Socket to CAsyncSocket (this will create the CSocketWnd as well) Another key point: because a socket inherits its parents async select settings, the parent should only be getting accept notifications (you then set the child's settings in the select call -- this is probably all you need to do to get your code working). Les Hill leh@cybercom.net -----From: odecio@ISF.COM I'll give it a try. The problem is that you are sending the *this* pointer to the working thread, and accept()-ing the socket referencing it. That is probably the reason why you receive the notifications in the _main_ thread. As I remember, a working thread does not deal with Windows messages. (and the socket notifications are such). Maybe you should use CWinThread as a basis for a new class that contains a CSocket, and your main thread keeps a list of them. Hope this helps. Otavio
| Вернуться в корень Архива |