Based on you're post, I assume you're using TCP/IP since you're referring to streaming, but a socket can be used for UDP connectionless protocol as well (and others). UDP is very easy, since you only send around fixed messages (no streaming).
Anyways, since you're referring to receive a stream of messages, I must assume you're using TCP/IP, and if you're using the socket directly, there are some major problems with what you're looking for.
TCP/IP is a stream solution, so sort of what I drop in one end comes out the other, and it will always be in order, but not necessarily together. So if on one end you write "Hello World", when reading you might get "Hello World", or "Hello" and "World", or even "H" "ello World". The point is, there is no way to call read and expect to receive the entire message.
The way I have done this in the past, is to just have an intermediary thread (or in my case, I simply used the .net thread pool), that reads the socket quickly, re-assembles messages, and then passes them on to a queue to be processed. The trick is the re-assembly, since you don't know what you receive. Say in you're header, the message length is an int32, that's 4 bytes. When you call read, you may even need to re-assembly this length, since you only received the first byte out of the 4 bytes you need to tell the length.
It sounds like you're header is fixed length, so basically what you need to do, assuming callerid and length are uint32's. Try and read 8 bytes, if less than 8, put into a buffer, until we read 8 bytes. Once we read the 8 bytes, take the 4 bytes and get the length, allocate a buffer for the length of the message. Try and read until we've filled the buffer, once we have, put that onto the queue for the specific callerid, and signal the thread that there is a new message in case it's sleeping. Then take whatever is left over, and start over, or wait for more data.
I have used this with success in the past, and it adds relatively little overhead.