gotAMessage()

In gotAMessage(), you see the other half of the functionality, where we add a client to the list of clients waiting for data (if it's a MT_WAIT_DATA message), or we match up a client with the message that just arrived (if it's a MT_SEND_DATA message). Note that for simplicity we didn't add a queue of clients that are waiting to send data, but for which no receiver is yet available—that's a queue management issue left as an exercise for the reader!

/*
 *  gotAMessage
 *
 *  This routine is called whenever a message arrives.  We
 *  look at the type of message (either a "wait for data"
 *  message, or a "here's some data" message), and act
 *  accordingly.  For simplicity, we'll assume that there is
 *  never any data waiting.  See the text for more discussion
 *  about this.
*/

void
gotAMessage (int rcvid, ClientMessageT *msg)
{
    int i;

    // determine the kind of message that it is
    switch (msg -> messageType) {

    // client wants to wait for data
    case    MT_WAIT_DATA:

        // see if we can find a blank spot in the client table
        for (i = 0; i < MAX_CLIENT; i++) {

            if (!clients [i].in_use) {

                // found one -- mark as in use, save rcvid, set timeout
                clients [i].in_use = 1;
                clients [i].rcvid = rcvid;
                clients [i].timeout = 5;
                return;
            }
        }

        fprintf (stderr, "Table full, message from rcvid %d ignored, "
                         "client blocked\n", rcvid);
        break;

    // client with data
    case    MT_SEND_DATA:

        // see if we can find another client to reply to with
        // this client's data
        for (i = 0; i < MAX_CLIENT; i++) {

            if (clients [i].in_use) {

                // found one -- reuse the incoming message
                // as an outgoing message
                msg -> messageType = MT_OK;

                // reply to BOTH CLIENTS!
                MsgReply (clients [i].rcvid, EOK, msg,
                          sizeof (*msg));
                MsgReply (rcvid, EOK, msg, sizeof (*msg));

                clients [i].in_use = 0;
                return;
            }
        }

        fprintf (stderr, "Table empty, message from rcvid %d ignored, "
                         "client blocked\n", rcvid);
        break;
    }
}