NetworkStreams impractical?, Buffering NetworkStreams, how?

  • Thread starter Yechezkal Gutfreund
  • Start date
Y

Yechezkal Gutfreund

For practical purposes, the CF network stream is really not a stream at all.
You can't peek, you can't push things back on the stream, etc.

We are sending packets on the stream with packet seperation marks,

The problem is that one can easily do a read that gets half of two packets,
or other malignant cases. We would like to read just as much to get the tail
of the first packet (and match it with what we read) and leave the second
packet on the stream till the rest arrives.

Logically, this is buffered stream.

The problem is that BufferedStreams are not supported in CF, nor is peek, or
seek, which would allow us to set the stream pointer to the actual logical
packet break.

What are people doing to get around this limitation?



--
==================================
Yechezkal Gutfreund
Chief Scientist
Kesser Technical Group, Inc.
==================================
 
P

Paul G. Tobey [eMVP]

I think that you're looking at it the wrong way. The network data *does*
appear as a stream (not as a set of discrete packets). The best way to
write your protocol, if you have control over that is to send a header
before you send your 'packet'. The header can contain whatever information
you want, but should include the length of the packet which is to follow.
On the receiving end, you can always assume that the first thing that will
come across will be a header, so you read that many bytes (you don't care
whether the header actually comes across as a single packet or a hundred
packets; that's entirely hidden from you). Once you have the header, you
know how many bytes are to follow, so you receive that many. Again, you
don't care whether the actual data comes in one packet or fifty. When the
receive completes, you know that you have the packet contents. You can then
return to waiting for a header, etc.

If you don't have control over your protocol and it was written what I would
call incorrectly, you can buffer the data yourself, allowing push-back, if
you want. That is, you'd create a class which encapsulates the network
stream, has send(), receive(), connect(), etc. methods, maybe, but adds the
ability to push data back. When data is pushed back, you need to store it in
some memory buffer in your class. When a receive is done while there is
data in the push-back buffer, you return that data first, then, when the
push-back buffer is empty, return to getting your data from the network
stream.

Paul T.
 
Y

Yechezkal Gutfreund

Option #1 is not robust, since headers can also be fragmented across reads.

Option #2 was what I was looking for. Basically, it means you write your own
BufferedStream for the
CF. I guess I was hoping for a revelation that there was something there I
was not seeing. But you are correct,
writing one's own BufferedStream is not RocketScience.

The only thing to note is that without this, network streams cannot be made
robust. So, why did MS not put BufferedStreams to begin with into the Net
CF?

Probably most people are relying on short packets fitting in an TCP MTU,
which is not a safe thing, (especially if one is doing wireless
communication).
 
P

Paul G. Tobey [eMVP]

Yes, but, if you ask, in a read, for x bytes and get only x-4 back, you can
simply ask for the other four (this is not going to happen very often, if
ever, unless you have a *huge* header or a very small actual transmission
size). I wouldn't call that a problem with robustness, although it's
obviously not as easy as it might be.

I'm sure it was a combination of the size of the code at run-time and time
available to port it. The .NET CF team is *not* some huge group of people
who occupy a large building in Redmond. It's a small group of people.

Paul T.
 
Y

Yechezkal Gutfreund

Gotcha on point #2. Having been part of a small team at DEC, part of an OS
development group that had a huge customer base, I am well aware of how a
small team can produce as much as the much larger OS groups.

On point #1, since our situation is wireless network stream, they have to be
assumed to be lossy, and break at times, so one cannot keep waiting for a
particular byte to arrive, or you will get deadlock by indefinite
postponement.

Right now we have a re-transmit scheme which is dealing with this, combined
with a 2-way (and sometimes) 3-way handshake.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top