Friday, November 13, 2009

Example: A Socket Message Receive Function









Example: A Socket Message Receive Function


It is frequently convenient to send and receive messages as a single unit. Named pipes can do this, as shown in Chapter 11. Sockets, however, require that you create a message header with a length field, followed by the message itself. The following function, ReceiveMessage, receives such a message and will be used in the examples. The SendMessage function is similar.


Notice that the message is received in two parts: the header and the contents. A user-defined MESSAGE type with a 4-byte message length header is assumed. Even the 4-byte header requires repetitive recv calls to ensure that it is read in its entirety because recv is not atomic.


Win64 note:
The message length variables have the fixed-precision LONG32 type to ensure the length, which is included in messages that may be transferred to and from non-Windows systems, and have a well-defined length, even after future recompilation for Win64 (see Chapter 16).



DWORD ReceiveMessage (MESSAGE *pMsg, SOCKET sd)
{
/* A message has a 4-byte length field, followed
by the message contents. */
DWORD Disconnect = 0;
LONG32 nRemainRecv, nXfer;
LPBYTE pBuffer;
/* Read message. */
/* First the length header, then contents. */
nRemainRecv = 4; /* Header field length. */
pBuffer = (LPBYTE) pMsg; /* recv may not */
/* transmit the number of bytes requested. */
while (nRemainRecv > 0 && !Disconnect) {
nXfer = recv (sd, pBuffer, nRemainRecv, 0);
Disconnect = (nXfer == 0);
nRemainRecv -=nXfer; pBuffer += nXfer;
}
/* Read the message contents. */
nRemainRecv = pMsg->RqLen;
while (nRemainRecv > 0 && !Disconnect) {
nXfer = recv (sd, pBuffer, nRemainRecv, 0);
Disconnect = (nXfer == 0);
nRemainRecv -=nXfer; pBuffer += nXfer;
}
return Disconnect;
}









    No comments:

    Post a Comment