"Assertion failed - <app name>:File sockcore.cpp" error message when you use a multi-threaded application that uses MFC's socket classes (140527)
The information in this article applies to:
- The Microsoft Foundation Classes (MFC), when used with:
- Microsoft Visual C++, 32-bit Editions 2.1
- Microsoft Visual C++, 32-bit Editions 2.2
- Microsoft Visual C++, 32-bit Editions 4.0
- Microsoft Visual C++, 32-bit Editions 4.1
- Microsoft Visual C++, 32-bit Enterprise Edition 4.2
- Microsoft Visual C++, 32-bit Enterprise Edition 5.0
- Microsoft Visual C++, 32-bit Enterprise Edition 6.0
- Microsoft Visual C++, 32-bit Professional Edition 4.2
- Microsoft Visual C++, 32-bit Professional Edition 5.0
- Microsoft Visual C++, 32-bit Professional Edition 6.0
- Microsoft Visual C++, 32-bit Learning Edition 6.0
- Microsoft Visual C++ .NET (2002)
- Microsoft Visual C++ .NET (2003)
This article was previously published under Q140527 SYMPTOMS A multi-threaded application that uses MFC's socket classes
encounters a message box or debug output line that contains an error message
similar to the following: For Visual C++ 2.x:
Assertion failed - <app name>:File sockcore.cpp, Line 837 For
Visual C++ 4.0: Assertion failed - <app name>:File
sockcore.cpp, Line 1041 CAUSE 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. RESOLUTION As already mentioned, 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. Use this sequence: - Use Detach() to detach the CAsyncSocket object from the
SOCKET handle in the thread that is currently using the CAsyncSocket
object.
- 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.
The code shown in the "Code Sample" section of this article
shows how to handle the moment when a listening socket accepts a connection
request and then begins a new thread to handle the new connection. Note One concern often arises that socket notification messages might
be lost between the time the call to Detach() is made and the subsequent call
to Attach() is made. This is not a concern because of the way socket
notifications are handled. The implementation of CAsyncSocket::Attach() makes a
call to WSAAsyncSelect to enable notifications. As mentioned in the
documentation for WSAAsyncSelect, if any socket notifications were already
pending for the SOCKET, they will be re-posted. REFERENCES MFC Technical Note #2 - Although this technical note does
not directly address the CAsyncSocket class, it does discuss the mapping of
handles to objects. The relationship between a SOCKET handle and a CAsyncSocket
object is maintained in much the same way.
Modification Type: | Major | Last Reviewed: | 9/1/2005 |
---|
Keywords: | kberrmsg kbcode kbprb kbThread kbWinsock KB140527 kbAudDeveloper |
---|
|