Laden...

Chatprogramm erstellt nur einen Client/einen Thread statt mehrere Clients

Erstellt von PaddelCore vor 5 Jahren Letzter Beitrag vor 5 Jahren 1.476 Views
P
PaddelCore Themenstarter:in
17 Beiträge seit 2018
vor 5 Jahren
Chatprogramm erstellt nur einen Client/einen Thread statt mehrere Clients

Hi, ich nutze VisualStudio 2015 und möchte gerne einen kleinen Chat programmieren. Dafür habe ich mir ein Beispielsprogram aus dem Netz geholt. Ich schaffe es auch, dass sich Clients verbinden können. Auf der grafischen Oberfläche wird allerdings immer nur ein Client angezeigt und die Daten verarbeitet. Auch im Debugger sehe ich nicht, dass ein weiter Thread geöffnet wird. Hat vlt jemand eine Idee?
LG

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ServerChatGrafisch
{
    public partial class Index : Form
    {
        BackgroundWorker worker;
        private TcpListener server;
        private Boolean isRunning = false;
        delegate void addString(String name);

        private StreamReader sReader;
        private StreamWriter sWriter;

        public Index()
        {
            
            InitializeComponent();
        }

        private void bStart_Click(object sender, EventArgs e)
        {
            if (!isRunning)
              {
                lVerbidnung.Text= "Verbunden unter dem Port: "+ tPort.Text;
                server = new TcpListener(Int32.Parse(tPort.Text));
                server.Start();
                TcpClient newClient = server.AcceptTcpClient();

            
                Thread t = new Thread(new ParameterizedThreadStart(HandleClient));
                t.Start(newClient);
            }
        }
 
        private void addUser(String user)
        {
            if (this.listUser.InvokeRequired)
            {
                MethodInvoker del = delegate { addUser(user); };
                this.listUser.Invoke(del);
            }
            else
            {
                this.listUser.Items.Add(user);
            }
        }
        private void addText(String user, String text)
        {
            if (this.listUser.InvokeRequired)
            {
                MethodInvoker del = delegate { addText( user, text); };
                this.lbChat.Invoke(del);
            }
            else
            {
                this.lbChat.Items.Add(user + ": " + text);
            }
        }
        public void HandleClient(object obj)
        {
            String name;
        
            TcpClient client = (TcpClient)obj;

           
                // sets two streams
            StreamWriter sWriter = new StreamWriter(client.GetStream(), Encoding.ASCII);
            StreamReader sReader = new StreamReader(client.GetStream(), Encoding.ASCII);


            
            Boolean bClientConnected = true;
            String sData = null;
            name = sReader.ReadLine();
            addUser(name);
            while (bClientConnected)
            {
                Thread.Sleep(5000);
                // reads from stream
                sData = sReader.ReadLine();

                // shows content on the console.
                addText(name, sData);
                Console.WriteLine("Client " + name + " " + sData);

                // to write something back.
                sWriter.WriteLine(name + " " + sData);
                sWriter.Flush();
            }
        }

        private void lbChat_SelectedIndexChanged(object sender, EventArgs e)
        {

        }
    }
}


16.807 Beiträge seit 2008
vor 5 Jahren

Das ist immer das Problem, wenn man irgendwo Code kopiert, ohne ihn zu verstehen.
Der Code jedenfalls ist nicht dafür ausgelegt, dass sich mehrere Clients verbinden; der Code unterstützt - und das sogar sehr unsauber - nur ein Client.

Jedenfalls suggeriert das die Stelle, dass nach dem Accept kein weiterer Accept erfolgt. Das müsste asynchron in einer Schleife abgefragt werden - tut es hier im Code aber nicht.
Das erklärt auch, wieso es kein neuen Thread gibt: es passiert einfach auch im Code nicht.

Übrigens ein super Fehlern, den man mit
[Artikel] Debugger: Wie verwende ich den von Visual Studio?
selbst analysieren kann.

P
PaddelCore Themenstarter:in
17 Beiträge seit 2018
vor 5 Jahren

Hi Abt, danke für die Antwort. Ich hatte jetzt nicht das Gefühl, dass ich den Code nicht verstanden habe. Ich hab das if einfach übersehen und ein while draus gemacht. Ich glaube, dass es gestern einfach zu spät war 😉

Es läuft auf jeden Fall.
LG

16.807 Beiträge seit 2008
vor 5 Jahren

Einfach aus dem if ein while machen kann auch nich stimmen; zum Einen würdest Du dann auch ständig einen neuen TcpListener instanziieren und zum Anderen würde die UI blockieren; weil AcceptListener eine blockierende Methode ist.

P
PaddelCore Themenstarter:in
17 Beiträge seit 2018
vor 5 Jahren

Ja, ich hab die while Schleife an eine andere Stelle gesetzt:

 private void bStart_Click(object sender, EventArgs e)
        {
            
            lVerbidnung.Text= "Verbunden unter dem Port: "+ tPort.Text;
            Thread t = new Thread(HandleConnection);
            t.Start();

        }
        public void HandleConnection()
        {
            server = new TcpListener(Int32.Parse(tPort.Text));
            server.Start();
            while (!isRunning)
            {
           
                TcpClient newClient = server.AcceptTcpClient();


                Thread t = new Thread(new ParameterizedThreadStart(HandleClient));
                t.Start(newClient);
            }
        }

Das ist der COde und er funktioniert. 😃