21b412cd98
In Java, control messages were parsed using manual buffering, which was convoluted and error-prone. Instead, read the socket directly through a DataInputStream and a BufferedInputStream. Symmetrically, use a DataOutputStream and a BufferedOutputStream to write messages.