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