With .NET and C++, when using the CSocket class for creating a Client and a
Server, both using the CSocketFile and CArchive classes to transmit/receive
data, it appears that the Client socket sometimes completes the send
operation ( Serialize() followed by Flush() ) yet the WM_SOCKET_NOTIFY
message is never posted to the Server (using Spy++ the message never appears,
the Server never receives notification of the message, the Server is actively
checking for posted messages).
The Client and Server DLLs are running in different applications, the
threads of each are running fine.
This problem never occured in code generated by Visual Studio 6, it started
when we started using VS.NET 2003.
This problem occurs on about 50% of the PC's we've tested the applications
on, running on Windows XP and Windows 2000.
Any ideas on what could be the problem?
Thanks,
Dave
"Peter Huang" [MSFT] - 22 Apr 2005 07:09 GMT
Hi
Here is a similar problem you may have a look.
http://groups.google.co.jp/group/microsoft.public.dotnet.languages.vc.librar
ies/browse_thread/thread/921bfcc4627375e5/9045915d20bd5cbe?q=%22WM_SOCKET_NO
TIFY+just+stops&rnum=1&hl=zh-TW#9045915d20bd5cbe
1. Workarounds:
In the short-run, if making significant changes is difficult given the time
frame, you may try disabling FD_READ notification in OnReceive.before the
Receive calls and re-enable the events when exiting:
OnReceive()
{
AsyncSelect(0); //disable all notification //or AsyncSelect (FD_WRITE |
FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE); //disable FD_READ
?
Receive();
?
Receive();
?
AsyncSelect(FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT |
FD_CLOSE);
}
The other method you may try is to prime the thread's message pumping by
doing:
OnReceive()
{
?
Receive();
?
Receive();
?
AsyncSelect(0);
AsyncSelect(FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT |
FD_CLOSE);
}
The above two methods should be temporary arrangement.
2. Limitation of CSocket w/ CArchive: CSocket::SendChunk blocking when
sending large data blocks both ways. Note that CArchive has an internal
buffer of 4k.
Windows Sockets: Using Sockets with
Archives?(http://msdn.microsoft.com/library/en-us/vccore98/HTML/_core_window
s_sockets.3a_.using_sockets_with_archives.asp)
"Keep in mind that a given CArchive object moves data in one direction
only: either for loading (receiving) or storing (sending). In some cases,
you’ll use two CArchive objects, one for sending data, the other for
receiving acknowledgments.?
"Windows Sockets: How Sockets with Archives Work"
(http://msdn.microsoft.com/library/en-us/vccore98/HTML/_core_windows_sockets
.3a_.how_sockets_with_archives_work.asp)
"A CSocket object is actually a two-state object: sometimes asynchronous
(the usual state) and sometimes synchronous. In its asynchronous state, a
socket can receive asynchronous notifications from the framework. But
during an operation such as receiving or sending data the socket becomes
synchronous. This means the socket will receive no further asynchronous
notifications until the synchronous operation has completed. Because it
switches modes, you can, for example, do something like the following:
CMySocket::OnReceive( )
{
// ...
ar >> str;
// ...
}
"If CSocket were not implemented as a two-state object, it might be
possible to receive additional notifications for the same kind of event
while you were processing a previous notification. For example, you might
get an OnReceive notification while processing an OnReceive. In the code
fragment above, extracting str from the archive might lead to recursion. By
switching states, CSocket prevents recursion by preventing additional
notifications. The general rule is: no notifications within notifications."
Also here is a KB article for your reference.
MFCSocs.exe Avoids Two Common MFC Socket Mistakes
http://support.microsoft.com/?id=185728
Best regards,
Peter Huang
Microsoft Online Partner Support

Signature
Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.