Add read-ahead logic.

This is my proposed synchronous solution to #65. It involves optimistically reading up to 9 extra frames from the connection each time we read a single frame.

The logic continues to implement a 'block until at least one frame is read' behaviour. That's important, we rely on that blocking IO (though arguably we shouldn't). We then read up to 9 more frames without blocking.

This is not quite complete, I need to do a bit more of a refactor to finish this off.
Why not? We're using sockets here, so it should be fine.