Es soll einen zentralen Server geben der alle eingehenden Verbindungen annimmt und die Texte in einer Listbox anzeigt. Bei der Annahme soll in einer 2. Box die IP-Adresse angezeigt werden und anschließend auch der einloggende Name später dann auch. In der ComboBox sollen dann die IPs angezeigt und auswählbar sein. Soweit funktioniert das auch.
Der Client loggt sich per Console ein sendet per Stream erst seinen Namen dann den Text und empfängt auch eine Bestätigung der Sendung.
Noch nicht implementiert, dass alle auch alle Nachrichten sehen und das der Server Nachrichten senden kann, da ich erst die anderen Probleme lösen möchte.
Problem 1:
Mit dem Kick-Button soll die Verbindung mit ausgewählten IP-Adresse in der Combobox getrennt werden. Ich weiß nicht wie ich die beenden kann.
Problem 2:
Ich kann den Server nicht beenden, da die while-Schleife in HandleConnection() mit dem interrupt des Threads nicht beendet wird und immer ein Fehler wirft, da AcceptTcpClient() wahrscheinlich noch auf Verbindungen wartet und wenn der Server gestoppt wird den Fehler erzeugt.
Frage 1: Der Thread t läuft ja in einer Schleife und erzeugt pro eingehende Verbindung einen neuen Thread tc. Wie kann ich die Threads auflisten oder unterscheiden bzw. darauf zugreifen? Später soll eine maximale Anzahl an Verbindungen eingebaut werden und Dopplungen von IPs vermieden werden.
Frage 2: Ist die Prozessstruktur so einigermaßen in Ordnung? Oder sollte ich sie grundsätzlich ändern?
Vielen Dank schon mal im Voraus, und bitte seid nachsichtig ich bin blutiger Anfänger!
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Chat_Server
{
public partial class Form1 : Form
{
private TcpListener server;
private Boolean isRunnig = false;
private Thread t;
public Form1()
{
InitializeComponent();
}
public void btn_server_start_Click(object sender, EventArgs e)
{
isRunnig = true;
t = new Thread(HandleConnection);
t.Start();
LBox_chat.Items.Add("Server gestartet!");
Thread aktualisieren = new Thread(cBox_aktualisieren);
aktualisieren.Start();
}
private void btn_server_close_Click(object sender, EventArgs e)
{
isRunnig = false;
t.Interrupt();
server.Stop();
LBox_chat.Items.Add("Server gestoppt!");
}
private void btn_send_Click(object sender, EventArgs e)
{
tBox_eingabe.Text = "";
}
private void btn_client_kick_Click(object sender, EventArgs e)
{
LBox_chat.Items.Add(" wurde vom Server gekickt!");
}
private void HandleConnection() //Zuweisungen der Ankommenden Verbindungen
{
server = new TcpListener(System.Net.IPAddress.Any, 5732);
server.Start();
while (isRunnig)
{
TcpClient newClient = server.AcceptTcpClient();
Thread tc = new Thread(new ParameterizedThreadStart(HandleClient));
tc.Start(newClient);
LBox_clients.Invoke(new Action(() => LBox_clients.Items.Add(newClient.Client.RemoteEndPoint.ToString())));
}
}
public void HandleClient(object obj) //Methode der einselnen Clients zum lesen und schreiben
{
String name;
TcpClient client = (TcpClient)obj;
StreamWriter writer = new StreamWriter(client.GetStream(), Encoding.ASCII);
StreamReader reader = new StreamReader(client.GetStream(), Encoding.ASCII);
Boolean bClieantConnectet = true;
String sData = null;
name = reader.ReadLine();
LBox_chat.Invoke(new Action(() => LBox_chat.Items.Add(name + " hat sich eingeloggt")));
LBox_clients.Invoke(new Action(() => LBox_clients.Items.Remove(client.Client.RemoteEndPoint.ToString())));
LBox_clients.Invoke(new Action(() => LBox_clients.Items.Add(name+" "+client.Client.RemoteEndPoint.ToString())));
while (bClieantConnectet)
{
sData = reader.ReadLine();
if (sData != null)
{
LBox_chat.Invoke(new Action(() => LBox_chat.Items.Add(name + ": " + sData)));
writer.WriteLine("Du hast eine Nachricht erfolgreich gesendet");
writer.Flush();
}
if (sData == "ende")
{
bClieantConnectet = false;
client.Close();
LBox_chat.Invoke(new Action(() => LBox_chat.Items.Add(name + " hat sich ausgeloggt")));
client.Close();
break;
}
}
}
public void cBox_aktualisieren()
{
while (true)
{
int counter = LBox_clients.Items.Count;
if (counter != cBox_cliens.Items.Count)
{
cBox_cliens.Invoke(new Action(() => cBox_cliens.Items.Clear()));
if (counter > 0)
{
for (int i = 0; i < counter; i++)
{
cBox_cliens.Invoke(new Action(() => cBox_cliens.Items.Add(LBox_clients.Items[i])));
}
}
}
}
}
}
}