"sc" <a_quarius3-***@yahoo.ca> wrote in message news:***@i40g2000cwc.googlegroups.com...
| What gets lost when? I follow the message sent by the client to the
| server (received by the server), and the server sends a message back
| (not received by the client).
|
| I tried to find a relevant post you mentioned - I'd appreciate if you
| could re-send it, or let me know when it was written.
|
| Thanks !!
|
[clipped from archive...]
"Bill Brehm >" <<don't want any spam> wrote in message news:***@TK2MSFTNGP12.phx.gbl...
| Thanks everyone. I have it working pretty well now.
|
| "Scott McPhillips [MVP]" <org-dot-mvps-at-scottmcp> wrote in message
| news:***@TK2MSFTNGP12.phx.gbl...
| > Scott McPhillips [MVP] wrote:
| >> Shutdown is a blocking call.
| >
| > My "gracefull close" wrapper, based on the defensive design
| > recommendations of Quinn & Shute in "Windows Sockets Network
Programming"
| >
| > int nbytes;
| > BYTE buf[4096];
| > ShutDown(1); // SD_SEND
| > do {
| > nbytes = CAsyncSocket::Receive(buf, 4096);
| > } while (nbytes != SOCKET_ERROR && nbytes > 0);
| > CAsyncSocket::Close();
| >
| > --
| > Scott McPhillips [VC++ MVP]
| >
|
Uh oh... the code snippet you submitted above will expose you to an infinite
hang condition if the socket fails to receive data. You should always 'look
ahead' to see if data is available before calling Receive(): For example,
DWORD dwStartTick = GetTickCount(), dwBytes = 0;
while(0 == dwBytes)
{
// Look ahead via IOCtl
if(!IOCtl(FIONREAD, &dwBytes))
{
TRACE("IOCtl FIONREAD Failed");
return; // Fatal
}
if(dwBytes)
break;
Sleep(25);
if(GetTickCount() - dwStartTick > HOST_TIMEOUT)
{
TRACE("TIMEOUT");
return;
}
}
Now it is safe to call Receive(). It is always unwise to call a blocking
Receive() without knowing there is something to receive or not. Adding a
Sleep() call and a timeout value further improves product stability and
prevents CPU overloading while awaiting data.
- Ed.
=========================================================================
P.S., Although Receive() is advertised as a non-blocking call, tracing it
through to its base class reveals that it does actually call recv() without
verifying that data exists yet, resulting in a condition where messages are
being pumped, but no response gets received from the other end. In later
versions of the MFC libraries this might have been fixed, but in the VC 6
libs it is not.