4 bytes (u32) should be more that enough to represent the payload's size. You are using usize, which depends on the platform - imagine what would happen if one end was compiled for a 32-bit architecture and the other was 64-bit.
You have two calls to read. read doesn't guarantee reading till the end of the buffer. use read_exact instead (unless you want to check the bytes read, and call read again in a loop...).
You should probably make an upper limit for json_size. Your program will crash (OOM) if the received json_size is too big.
If network speed is the bottleneck - JSON tends to compress well.
It's about calling read_exact instead of read on both instances.
Example:
You want to read the payload size (4 bytes), so you call read. But the OS only does a partial 1 byte read (read returns Ok(1)). You will need call read more times to get the full payload size. The same goes for the payload data - where this might actually occur.
In essence, you read a big chunk all at once (maybe 4k?). Then you check the length, and read out the rest that you need, but it's already in memory, so you aren't making more syscalls. If it was too much, the buffer holds the rest until you ask for it. If it wasn't enough, you get what's in the buffer then make another call to get the rest.
Yes! There's no way you can guarantee one system read per item of unknown size, but with buffered input and items of generally modest size, you're very likely to get most items in one system read. With separate reads for size and content, that will be two system reads for most items.