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