Zerowalker
Zerowalker

Reputation: 767

How to tell when the Stream is at it's end?

How do I embed or tell the size of the TCP Stream to the receiver without using BinaryWriter/Reader?

There must be a fast way for it to know if it has reached the end, except of course, killing the connection.

tcp.GetStream().Write(ms.GetBuffer(), 0, (int)ms.Length);

I am sending like that, but receiving is the hard part.

EDIT:

This does not work for me:

                while (tt1.GetStream().DataAvailable)
                {
                    su = Image.FromStream(tt1.GetStream());
                }

Upvotes: 2

Views: 8058

Answers (2)

Jim Mischel
Jim Mischel

Reputation: 134125

No, there isn't a way (fast or slow) to tell when you've reached the end of a network stream. DataAvailable will tell you if data is currently available, but it can't tell you if more data might be coming down the stream.

There are two reliable ways that I know of to determine if you've reached the end of a network stream:

  1. Have the sender send the length (an int or long) as the first 4 (or 8) bytes of the stream. The receiver reads this length and then continues to read the stream until it's read that many bytes.
  2. Agree on an "end of stream" marker. This can take many forms. For simple streams that contain only ASCII strings, for example, you could agree that a byte value of 255 means end of string. Or you could use the ASCII EOT character. For record-oriented strings, the first byte of the record could be the record type, and a record type of 0xFF could mean "End of records."

In other words, a network stream can't know when it's at the end. Not like a file stream can. You have to encode the stream length or end of stream marker in your data.

Update

Documentation for System.Drawing.Image.FromStream says:

The stream is reset to zero if this method is called successively with the same stream.

So you can't use that method to read multiple images from the same stream.

I suspect what you'll need to do is change your data so that it is structured like this:

length | data for image 1 | length | data for image 2 | 0

Then you'll read the length, read that many bytes into a byte array, and create the image from that byte array (perhaps by wrapping a memory stream around it), then read the next length, the next block of bytes, etc., until you read a length of 0, which signifies the end of the stream.

Upvotes: 6

Rob G
Rob G

Reputation: 3526

You can use the .DataAvailable property in the receiver to determine if there is still data available in the stream to be read, but the Length property itself is not implemented.

Use

do {
    ...
    myNetworkStream.Read(buffer, 0, someSizeToCopyEachLoop)
}
while(myNetworkStream.DataAvailable);

If you really need the length of the stream you can copy its contents to a MemoryStream and read the .Length property of that:

MemoryStream s = new MemoryStream();
myNetworkStream.CopyTo(s);
int length = s.Length;

Upvotes: 2

Related Questions