It’s amazing how many times we solve this same problem over-and-over. It’s so 
difficult because every case is slightly nuanced :(  

I agree with everything Jens said, as usual. A ring buffer is fastest, but if 
your max message size is unknown and you can’t do stream-style parsing, they’ll 
always be some nasty edge cases…

Just feeding into an NSMutableData is a good approach too and probably the most 
common. There are some downsides, such as multi-threaded parsing complexity and 
manually having to manage the addition and removal of data blocks.

A third tool in the arsenal is GCDs dispatch_data_t, which is very well suited 
for combining, traversing and removing arbitrarily-sized data blocks in a 
multi-threaded streaming environment. The downsides there are GCD's boilerplate 
overhead and a performance profile that is not always easy to reason about.  

— adam


On Wednesday, September 9, 2015 at 6:30 PM, Jens Alfke wrote:

>  
> > On Sep 9, 2015, at 2:07 PM, Motti Shneor <su...@bezeqint.net 
> > (mailto:su...@bezeqint.net)> wrote:
> > I need reading messages off the stream, each prefixed by 4 bytes containing 
> > its size. I was wondering if it was advisable to first read just the size 
> > (4 bytes) then read the rest of the message, or maybe it was better to have 
> > a big buffer into which to “drain” the stream, then parse my messages off 
> > the buffer?  
>  
> The first approach won’t work, because the amount of data received is 
> unpredictable. For instance you might receive only three bytes, which isn’t 
> enough to parse the data size. Or you might be able to read the data size, 
> but then try to read a 100000-byte message and get only 1500 bytes of it.
>  
> The usual approach when parsing data asynchronously from a network stream is 
> to keep a variable-size buffer of unparsed data. When data arrives, you read 
> all of it and append it to the buffer; then you try to parse the data in the 
> buffer. If there’s not enough to parse yet, you give up till there’s more; or 
> if you parse some data, you remove it from the start of the buffer.
>  
> So in your case you’d first check whether the buffer has at least four bytes; 
> if so, you look at the length, and check whether that many more bytes are 
> available. If they are, you read the whole message and remove it from the 
> buffer.
>  
> An NSMutableData object works well as a buffer, if you’re not too concerned 
> about high performance. The fastest implementation is probably some sort of 
> custom ring buffer.
>  
> —Jens
> _______________________________________________
> Do not post admin requests to the list. They will be ignored.
> Macnetworkprog mailing list (Macnetworkprog@lists.apple.com 
> (mailto:Macnetworkprog@lists.apple.com))
> Help/Unsubscribe/Update your Subscription:
> https://lists.apple.com/mailman/options/macnetworkprog/adkapx%40gmail.com
>  
> This email sent to adk...@gmail.com (mailto:adk...@gmail.com)  



 _______________________________________________
Do not post admin requests to the list. They will be ignored.
Macnetworkprog mailing list      (Macnetworkprog@lists.apple.com)
Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/macnetworkprog/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to