StreamReader funktioniert nicht

kletoris

Grünschnabel
Hallo,

ich habe ein Problem mit einem StreamReader und ich habe keine ahnung warum er nicht funktioniert. Ich hoffe ihr könnt mir helfen.
Code:
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace VerbindungKlasseTest
{
    static class Verbindung
    {
        // Enum das die Anfragen an den Server beschreibt
        public enum Status
        {
            LoginAkzeptiert,
            LoginAbgelehnt,
            RegistrationAkzeptiert,
            RegistrationAbgelehnt
        }
        #region Variablen

        // Die Variable die die aufzurufende Methode enthält
        internal static OnServerReceivesMessage NachrichtEmpfangenEvent;

        // Delegate zum aufrufen des Events
        internal delegate void OnServerReceivesMessage(string nachricht);

        // Die Verbindung zum Server
        private static TcpClient _server;

        // Zum lesen von Informationen aus dem Stream des Servers
        private static StreamReader _streamReader;

        // Zum schreiben von Informationen in den Stream des Servers
        private static StreamWriter _streamWriter;

        // Gibt an ob man Verbunden ist
        public static bool Verbunden { get; private set; }

        // Der Thread um Nachrichten zu Empfangen
        private static Thread _nachrichtEmpfangen;

        #endregion
        
        /// <summary>
        /// Die Verbindung zum Server aufbauen
        /// </summary>
        /// <param name="ipAddress">Die IP-Adresse des Servers</param>
        /// <param name="port">Der Port auf dem der Server läuft</param>
        public static void Verbinden(IPAddress ipAddress, int port)
        {
            // Die verbindung instanzieren und verbinden
            _server = new TcpClient();
            _server.Connect(ipAddress, port);
            // Wenn man verbunden ist
            if (_server.Connected)
            {
                // StreamReader und Streamwriter mit dem Stream des Servers instanzieren
                NetworkStream stream = _server.GetStream();
                _streamReader = new StreamReader(stream);
                _streamWriter = new StreamWriter(stream);
                // Gibt an das man verbunden ist
                Verbunden = true;
                // Den Thread zum Nachrichten Empfangen starten
                _nachrichtEmpfangen =  new Thread(NachrichtEmpfangen);
                _nachrichtEmpfangen.Start();
            }
        }

        /// <summary>
        /// Die Verbindung zum Server trennen
        /// </summary>
        public static void Trennen()
        {
            if (Verbunden)
            {
                try
                {
                    if (_server != null)
                    {
                        _server.Close();
                    }
                    if (_streamReader != null)
                    {
                        _streamReader.Close();
                        _streamReader.Dispose();
                    }
                    if (_streamWriter != null)
                    {
                        _streamWriter.Close();
                        _streamWriter.Dispose();
                    }
                    if (_nachrichtEmpfangen.IsAlive)
                    {
                        _nachrichtEmpfangen.Abort();
                    }
                }
                finally 
                {
                    Verbunden = false;
                }
            }
        }

        /// <summary>
        /// Sendet eine Nachricht an den Server
        /// </summary>
        /// <param name="nachricht">Die zusendende Nachricht</param>
        public static void NachrichtSenden(string nachricht)
        {
            if (!string.IsNullOrEmpty(nachricht))
            {
                _streamWriter.WriteLine(nachricht);
                _streamWriter.Flush();
            }
        }

        private static void NachrichtEmpfangen()
        {
            while (Verbunden)
            {
                string read = _streamReader.ReadLine();
                BeiNachrichtEmpfangen(read);
            }
        }

        private static void BeiNachrichtEmpfangen(string nachricht)
        {
            OnServerReceivesMessage serverReceivesMessage = NachrichtEmpfangenEvent;

            if (serverReceivesMessage != null)
            {
                serverReceivesMessage(nachricht);
            }
        }
    }
}

Vielen Dank im Vorraus.

MfG
Klemens
 

kletoris

Grünschnabel
Es gibt keine Fehlermeldung, nur der StreamReader liest nichts vom Stream ein wenn ich von einem anderen Programm etwas sende.
 

deepthroat

Erfahrenes Mitglied
Hi.

Ich habe es gerade mal mit einem simplen Echo-Server ausprobiert und es funktioniert problemlos:
C#:
public static void RunSnippet()
	{
		Verbindung.Verbinden(IPAddress.Parse("127.0.0.1"), 50000);
		Verbindung.NachrichtEmpfangenEvent += (x) => { WL("server> {0}", x); };
		try {
			string l;
			while ((l = RL()) != null) {
				Verbindung.NachrichtSenden(l);
			}
		} finally {
			Verbindung.Trennen();
		}
	}
Gruß
 

kletoris

Grünschnabel
Warum funktioniert die Klasse nicht wenn ich sie so verwende:

C#:
public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            Verbindung.NachrichtEmpfangenEvent += AppendText;
        }

        private void AppendText(string nachricht)
        {
            textBox2.AppendText(nachricht);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                if (Verbindung.Verbunden)
                {
                    Verbindung.Trennen();
                }
                else
                {
                    Verbindung.Verbinden(IPAddress.Parse("127.0.0.1"), 1993);
                }
            }
            catch
            {
                MessageBox.Show("Fehler bei Verbindung");
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (textBox1.TextLength != 0 && Verbindung.Verbunden)
            {
                Verbindung.NachrichtSenden(textBox1.Text);
            }
        }
    }
 

sheel

I love Asm
Hi

nur mal so ins Blaue vermutet, ohne den kompletten Code gelesen zu haben:
Du willst den Textboxinhalt aus einem anderen Thread ändern.
Das mag .NET nicht ganz.
Mit einer Suche nach "Invoke invokerequired" findet man viele Beispiele, wie man das löst.

Gruß
 

kletoris

Grünschnabel
Mit Invoken funktionierts auch nicht :(

C#:
public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            Verbindung.NachrichtEmpfangenEvent += AppendText;
        }

        private void AppendText(string nachricht)
        {
            InvokeIfRequired(textBox2, (MethodInvoker) (() => textBox2.AppendText(nachricht)));
        }

        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                if (Verbindung.Verbunden)
                {
                    Verbindung.Trennen();
                }
                else
                {
                    Verbindung.Verbinden(IPAddress.Parse("127.0.0.1"), 50000);
                }
            }
            catch
            {
                MessageBox.Show("Fehler bei Verbindung");
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (textBox1.TextLength != 0 && Verbindung.Verbunden)
            {
                Verbindung.NachrichtSenden(textBox1.Text);
            }
        }

        private void InvokeIfRequired(Control target, Delegate methodToInvoke)
        {
            /* Mit Hilfe von InvokeRequired wird geprüft ob der Aufruf direkt an die UI gehen kann oder
             * ob ein Invokeing hier von Nöten ist
             */
            if (target.InvokeRequired)
            {
                // Das Control muss per Invoke geändert werden, weil der aufruf aus einem Backgroundthread kommt
                target.Invoke(methodToInvoke);
            }
            else
            {
                // Die Änderung an der UI kann direkt aufgerufen werden.
                methodToInvoke.DynamicInvoke();


            }
        }
 

Neue Beiträge