However, what concerns me is if the handler receives a buffer that has just 2.5 lines in it. All the messages from the server are going to be one line long. So if the server sends three messages in succession but say there is some network hiccup partway through the 3rd line, then my client will only receive 2.5 lines, and the handler will get called with the partial line? Then the handler has to cache the partial line so that when the rest of the line comes through it can paste them together again? That seems hard...
 
Right. The most simple way to accomplish this is to use asio::streambuf as a buffer. When you process the input data, you call consume() function only for the amout you've really processed, and the rest of the data remains unused in the streambuf - until the next time you get something from the server (look at the asio examples with streambuf).