RyanTimmons91
RyanTimmons91

Reputation: 460

c# Stream data not reading correctly

SOLVED Issue was I was assuming it got all the data at once when i told it to read, so it was escaping out of my READ SCREENSHOT method and dumping the data pack into my packet parser, which proceeded to spam my console with junk >.<

Thanks jon.

I have another new problem, this time I cant figure out whats wrong with my data streams, I'm currently attempting to stream image files that are captured to a central networked server, I have the Client > Server set up, talking just fine, passing data back and forth all day long, but when i attempt to call my screenshot function and send it, thats where i get my issues.

The current code im using for this is:

Notes DataHandler is just a wrapper for Sending and receiving data, AddVar is an overloaded method that takes any variable and sends it through a stream (new DataHandler(stream))

DataHandler is linked to the TCP Stream

ReadInt and ReadLong etc are the reverse, helper functions to facilitate making the code easier to maintain later.

At this point the Server sends out a ping every second, to the client, the client is set to respond to that ping IF it isnt busy responding to another packet (the incoming packets run on a single thread)

Server follows the same rule, per client

Writing the data to the stream at SI.TakeScreenShotAndStream, this method takes a screenshot of the client computer and streams the data to any stream passed, in this case the memorystream.

end note

(client side)

try
        {
            DataHandler.AddVariable((byte)50);
            memoryStream = new MemoryStream();
            SI.TakeScreenShotAndStream(memoryStream, quality);
            DataHandler.AddVariable(memoryStream.Length);
            memoryStream.Position = 0;
            memoryStream.CopyTo(clientStream);
            clientStream.Flush();
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
            Disconnect();
        }

and server side

if (!Directory.Exists(LoadedSettings.Directory + name)) Directory.CreateDirectory(LoadedSettings.Directory + name);
            fileStream = File.Create(FullPath);
            long length = DataHandler.ReadLong();
            byte[] data = new byte[length];
            clientStream.Read(data, 0, (int)length);
            fileStream.Write(data, 0, (int)length);
            fileStream.Flush();
            fileStream.Close();

The "Take screenshot and save" function works, i can stream that to a FileStream and save it directly to a file, my problem seems to be that I have no clue how to work with the MemoryStream class if I'm really far off the mark on how to do this, a nice tutorial for memory streams would be helpful.

At one point I attempted to convery MemoryStream into a byte array but that didnt work either.

Also as a note, this doesnt just mess up, both of these are encapsulated in try/catch statements and invalid packets (anything except 1, 2 and 50 atm), both exceptions and packet numbers that are invalid get logged to the console, when i run this code it spews so much to the console that it beeps constantly until i shut it off (there is no console.beep code anywhere in my program)

Any assistance would be appreciated :)

Upvotes: 0

Views: 2479

Answers (1)

Jon Skeet
Jon Skeet

Reputation: 1499770

It's the way you're reading the data here:

clientStream.Read(data, 0, (int)length);

Instead, you should use the value returned by Read:

// TODO: If you really want to handle more then 4GB per file, you'll need
// to change this...
int length = (int) DataHandler.ReadLong();
byte[] buffer = new byte[16 * 1024]; // Read up to 16K at a time

while (length > 0)
{
    int bytesRead = clientStream.Read(buffer, 0,
                                      Math.Min(length, buffer.Length));
    if (bytesRead <= 0)
    {
        // Throw an appropriate exception: the data is truncated
    }
    fileStream.Write(buffer, 0, bytesRead);
    length -= bytesRead;
}

Upvotes: 3

Related Questions