tryReadMessage
Stream-framing read. Treats buffer[offset until buffer.size] as a byte stream and tries to pull exactly one length-prefixed message off the front.
Returns the decoded message paired with the total number of bytes consumed (the 4 length bytes + the body), or null if fewer than a whole message is available yet, in which case the caller keeps buffering and retries. This is the codec half of libtorrent's m_recv_buffer packet machinery: read a 4-byte length, then wait for that many body bytes before dispatching.
A declared length of 0 is a keep-alive consuming 4 bytes. The length is read as unsigned; a peer announcing an absurd length (here, anything that would overflow a signed Int frame) yields a BadFrameLengthException so callers can disconnect rather than try to allocate it.