you have a buffer (a character array) where you store pieces of a message until you have a network newline ("\r\n"). Each message piece goes after the data that you've already placed in the buffer. When you find a network newline, you know that you have a complete message, so you can print that message and then shift any remaining bytes to the front of the buffer as the start of the next copy of the message.
int main() {
    // This line causes stdout not to be buffered.
    // Don't change this! Necessary for autotesting.
    setbuf(stdout, NULL);

    struct sockaddr_in *self = init_server_addr(PORT);
    int listenfd = set_up_server_socket(self, 5);

    while (1) {
        int fd = accept_connection(listenfd);
        if (fd < 0) {
            continue;
        }

        // Receive messages
        char buf[BUFSIZE] = {'\1'};
        int inbuf = 0;           // How many bytes currently in buffer?
        int room = sizeof(buf);  // How many bytes remaining in buffer?
        char *after = buf;       // Pointer to position after the data in buf

        int nbytes;
        while ((nbytes = read(fd, after, room)) > 0) {
            // Step 1: update inbuf (how many bytes were just added?)
            inbuf = nbytes;

            int where;
            while ((where = find_network_newline(buf, inbuf)) > 0) {
                                // where is now the index into buf immediately after
                                // the first network newline
                buf[where + 2] = '\0';
                                printf("Next message: %s\n", buf);
                // Step 4: update inbuf and remove the full line from the buffer
                // There might be stuff after the line, so don't just do inbuf = 0.
                inbuf -= where;
                memmove(buf, buf + where, sizeof(where) + 1);

            }
            // Step 5: update after and room, in preparation for the next read.
            after = buf;
            room = BUFSIZE - inbuf;
        }
        close(fd);
        printf("The connection is now closed ...\n");
    }

    free(self);
    close(listenfd);
    return 0;
}


/*
 * Search the first n characters of buf for a network newline (\r\n).
 * Return one plus the index of the '\n' of the first network newline,
 * or -1 if no network newline is found. The return value is the index into buf
 * where the current line ends.
 * 
 */
int find_network_newline(const char *buf, int n) {
    for (int i = 0; i < n - 1; i++) {
        if ((buf[i] == '\r') && (buf[i + 1] == '\n')) {
            return i + 2;
        }
    }

    return -1;
}