(Gelöst)Chat Client Thread problem



  • Hallo zusammen!!!

    Ich sitze momentan an einem kleinen chatprogramm um mich ein bisschen mit netzwerk und socketprogrammierung zu befassen. Da ich relativ neu auf diesem gebiet bin, bräuchte ich ein wenig hilfe.

    Ich würde gerne ein programminstanz als Portlistener verwenden und die andere als Client(lokal). Das ganze funktioniert auch weitgehenst, allerdings liegt eines der probleme darin, dass der teil des programmes der auf einkommenden verbindungen wartet in einem unabhängigen thread gestartet werden muss.
    Und genau da komme ich nicht weiter. Sobald ich über den klienten eine nachricht schreibe, stürzt die komplette gui ab.

    Hier einmal der source code( ist nocht nicht wirklich gut organisiert).

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    using System.Net;
    using System.Net.Sockets;
    using System.IO;
    
    namespace WindowsFormsApplication1
    {
    
        public partial class Form1 : Form
        {
            //Delegate
            delegate void myDelegate(String s);
            //Network Resources
            public TcpClient tcpClient;
            public NetworkStream nStream;
            public Thread thread;
    
            public Form1()
            {
                InitializeComponent();
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
    
            }
    
            private void label1_Click(object sender, EventArgs e)
            {
    
            }
    
            private void button3_Click(object sender, EventArgs e)
            {
                byte[] buffer = new byte[1024];
                buffer = Encoding.ASCII.GetBytes(richTextBox2.Text);
                nStream.Write(buffer, 0, buffer.Length);
                listBox1.Items.Add(richTextBox2.Text);
                richTextBox2.Text = "";
                richTextBox2.Text = "txtMessage";
            }
    
            private void textBox1_TextChanged(object sender, EventArgs e)
            {
    
            }
    
            private void richTextBox1_TextChanged(object sender, EventArgs e)
            {
    
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
             TcpListener tcpListener = new TcpListener(IPAddress.Any, 9000);
             tcpListener.Start();
             listBox1.Items.Add("Listening for a Client");
             tcpClient = new TcpClient();
             thread = new Thread(ReceivedData);
             thread.Start();
            }
    
            private void button2_Click(object sender, EventArgs e)
            {
                listBox1.Items.Add("Connecting...");
                tcpClient = new TcpClient(textBox1.Text, 9000);
                thread = new Thread(ReceivedData);
                thread.Start();
    
            }
    
            private void richTextBox2_TextChanged(object sender, EventArgs e)
            {
    
            }
    
            private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
            {
    
            }
            private void ListenToClient()
            {
    
            }
            private void ReceivedData()
            {
                int numberBytesRead = 0;
                String message;
                //Byte Array.
                byte[] buffer = new byte[1024];
                //NetworkStream for reading data.
                nStream = tcpClient.GetStream();
                //Delegate
                setText("Connected");
                //Loop condition
                bool condition = true;
                //Reading
                while (condition)
                {
                    numberBytesRead = nStream.Read(buffer, 0, buffer.Length);
                    //Read Bytes to String.
                    message = Encoding.ASCII.GetString(buffer);
                    if (message.Equals("Bye"))
                    {
                        condition = false;
                    }
                    //Adding String via Delegate to textbox
                    setText(message);
    
                }
                buffer = Encoding.ASCII.GetBytes("Bye");
                nStream.Write(buffer, 0, buffer.Length);
                nStream.Close();
                tcpClient.Close();
                setText("Connection Closed!!");
            }
            private void setText(String text)
            {
                if (this.listBox1.InvokeRequired)
                {
                    myDelegate md = new myDelegate(setText);
                    this.Invoke(md, new object[] { text });
                }
                else
                {
                    this.listBox1.Text = text;
                }
    
            }
    
        }
    }
    

  • Administrator

    tilli88 schrieb:

    Sobald ich über den klienten eine nachricht schreibe, stürzt die komplette gui ab.

    Es wäre praktisch, wenn du etwas genauer werden würdest bei deiner Fehlerbeschreibung:
    1. Genau erklären, was abläuft und ab welchem Punkt welches Programm abstürzt.
    2. Gibt die Fehlermeldung dazu an. Z.B. im Output-Fenster hast du die Exception drin, welche dein Programm zum Absturz brachte.
    3. Du könntest das Programm auch debuggen und prüfen, woran der Absturz liegt.

    Grüssli



  • Hallo,

    okay, ich probiere es ein bisschen deutlicher zu beschreiben.

    Wenn ich das programm starten möchte, dann läuft eine instanz im "listeningmode" und die andere als chat instanz. Sobald ich versuche auf eingehende verbindungen zu warten(von meiner lokalen IP), bzw. den btnListen button klicke, friert das fenster ein. Die klienteninstanz des programmes läuft jedoch weiter und ich kann nachrichten schreiben.

    Ich denke das es damit zu tun hat, das das warten auf einen klienten nicht in einem gesonderten thread stattfindet und die gui dadurch nicht zugänglich ist.

    Daher wäre meine hauptfrage, wie ich dies in einem eigenen thread realisieren kann.



  • Es fällt auf:
    Du erzeugst einen tcpListener, initialisiert den (mit der Start-Methode), machst dann aber nichts weiter damit?
    Für gewöhnlich folgt darauf eine Schleife, in der man eingehende Verbindungen mit z.B. AcceptTcpClient() annimmt.

    Stattdessen erzeugst du eine Instanz von TcpClient, die mit nichts verbunden wird und scheinst die dann im ReceivedData-Thread zu verwenden?


Anmelden zum Antworten