This commit adds a new MessageError type that is intended to allow the
caller to differentiate between general io errors and and errors that
resulted from malformed messages.
The io.ReadFull function always returns an error if the full payload can't
be read, so there is no reason to further check if the payload length
matches after a successful read.