There is a property called ReceiveBytesThreshold, which enables the event to fire when the number of bytes received reach this level. In my opinion, this should probably be set to a value of 1 (which is the default anyway) so no data is missed. (The operating system decides when this event is fired.)

This does not mean the event will fire for every byte, it merely means that it will fire if there is at least one byte available. It may be 1, it may be 6, it may be 10, etc.

When the event is fired, you can read how many bytes are available by querying the BytesToRead property before performing a Read into your own buffer.