Laden...

NetworkStream in Datei speichern + Fortschrittsanzeige des Downloads

Erstellt von emsch vor 10 Jahren Letzter Beitrag vor 10 Jahren 4.141 Views
E
emsch Themenstarter:in
10 Beiträge seit 2013
vor 10 Jahren
NetworkStream in Datei speichern + Fortschrittsanzeige des Downloads

Hey Leute.

Ich sitze nun schon seit ein paar tagen an diesem Problem, irgendwie versteh ich mittlerweile gar nichts mehr 🙁
Also ich möchte eine Datei von einem Clienten zum anderen Per TCP versenden. Die Clienten finden sich untereinander und auch die TCP-Verbindung funktioniert. Ich habe nur ein Problem mit der eigentlichen Dateiübertragung, hier erst mal mein code den ich bisher habe:
Senden:


            //Objekt mit dem remoteEndPoint und Infos zur Datei, diese Methode läuft in einem Thread
            SendingParams sp = (SendingParams)o;
            IPEndPoint remoteep = sp.remoteEP;
            
            //Informationen über Größe, Name, etc.
            FileInformation fi = sp.file;

            client = new TcpClient();
            client.ExclusiveAddressUse = false;
            client.Connect(remoteep);

            FileStream fs = File.Open(fi.LocalPath, FileMode.Open);
            NetworkStream netStream = client.GetStream();

            byte[] buffer = new byte[2 * 4096];
            int current = 0, all = 0; //all beschreibt die Gesamt-Anzahl der versendeten Bytes

            while (all < (int)finfo.FileLength)
            {
                current = fs.Read(buffer, 0, buffer.Length);
                netStream.Write(buffer, 0, buffer.Length);
                all += current;
                ProgressChange(all);
                Debug.WriteLine(Thread.CurrentThread.ThreadState.ToString());
            }

Empfangen:

 NetworkStream netStream = null;
            FileStream fs = null ;
            TcpClient tempclient = null;
            try
            {
                listen.Start();
                tempclient = listen.AcceptTcpClient();
                netStream = tempclient.GetStream();
                MessageBox.Show("Eingehende FileServer Verbindung");
                string outputFile = @"D:\" + finfo.FileName;

                using (Stream file = File.OpenWrite(outputFile))
                {
                    CopyStream(netStream, file);
                }

                MessageBox.Show("Datei Gespeichert");
            }
            catch (Exception ex) { Debug.WriteLine(ex.Message); }
            finally
            {

                netStream.Close();
                tempclient.Close();
                listen.Stop();
            }

        //gefunden auf stackoverflow
        public void CopyStream(Stream input, Stream output)
        {
            byte[] buffer = new byte[8 * 1024];
            int len,all = 0;
            do
            {
                len = input.Read(buffer, 0, buffer.Length);
                output.Write(buffer, 0, len);
                all += len;
                //Event wird in der Form behandelt, ProgressBar wird auf aktuelle Gesamtübertragung gesetzt
                ProgressChange(all);
            } while (((NetworkStream)(input)).DataAvailable);
        }

Um so mehr ich daran arbeite, desto weniger versteh ich. Insbesondere ist es mir mittlerweile echt schleierhaft geworden wie die Streams funktionieren, was die einzelnen Methoden im genauen machen.
Das Kapitel über Streams im OpenBook hab ich nun auch schon mehrfach durch, aber es hilft mir alles nicht mehr 😁
Man findet ja diverse Vorschläge á la

 while ( (len = input.Read(buffer, 0, buffer.Length)) > 0)

doch das funktioniert bei mir einfach nicht. kurz bevor die Datei komplett übertragen wäre hört die Ausführung des Codes einfach auf, alles was hinter dieser while-Schleife steht wird Ignoriert. Beim Debbuggen hab ich auch nichts gefunden, bin das Step-Weise durchgegangen aber nach dem while war einfach irgendwann Ende, keine Exception, nichts.. Nicht mal der Thread in dem das Empfangen geschieht endet.
Nutze ich einen anderen Ausdruck im while-Header wird der Code zumindest schonmal komplett ausgeführt, jedoch wird die Datei auch nicht richtig übertragen. Einmal war übertragene Datei doppelt so groß wie die Original Datei, ein anderes mal fehlten ein paar KB. Mittlerweile hab ich keine Ahnung mehr was ich ändern könnte bzw. was fehlerhaft ist.
Als eine weitere Möglichkeit habe ich die Mehtode Stream.CopyTo() gesehen. Ich möchte allerdings gerne eine Fortschrittsanzeige des Down- und Uploads anzeigen, sehe bei dieser Methode jedoch keine Möglichkeit soetwas einzubauen. Wahrscheinlich habe ich aber auch einen Falschen Denkansatz und das ist alles doch sehr einfach 😁
Deswegen bitte ich euch mir mal nen paar Denkanstöße zu geben 😉
Bei Unklarheiten stehe ich natürlich zur Verfügung.

5.941 Beiträge seit 2005
vor 10 Jahren

Hallo emsch

Wieso verwendest du die CopyStream-Methode nicht auch beim Senden?
Hast du schon mal versucht, es möglichst zu vereinfachen; ob es dann funktioniert?

Gruss Peter

--
Microsoft MVP - Visual Developer ASP / ASP.NET, Switzerland 2007 - 2011

4.221 Beiträge seit 2005
vor 10 Jahren

current = fs.Read(buffer, 0, buffer.Length);
netStream.Write(buffer, 0, buffer.Length); <-- current statt buffer.Length

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

E
emsch Themenstarter:in
10 Beiträge seit 2013
vor 10 Jahren

Schonmal danke für eure Vorschläge, habe im Moment leider nicht viel zeit, werde aber versuchen so bald wie möglich weiter dran zu arbeiten und gebe dann Rückmeldung ob es geklappt hat.

E
emsch Themenstarter:in
10 Beiträge seit 2013
vor 10 Jahren

Juhu, es funktioniert endlich 😃
Es lag wirklich daran dass ich beim Senden immer die Länge des Buffers in den netStream geschrieben habe und nicht die zuvor aus dem FileStream gelesene Menge...
Hätte ich auch dort einfach die CopyStream Methode genommen wäre der Fehler gar nicht aufgetreten, aber irgendwie war ich so gefrustet dass ich selbst nicht mehr wusste was ich jetzt schon alles probiert hatte und was da eigentlich abläuft... 😄
Also vielen Dank an euch beide 😃