Windows System Programming Third Edition [Electronic resources]

Johnson M. Hart

نسخه متنی -صفحه : 291/ 180
نمايش فراداده

  • 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;
    }