Guten Tag
Mein Projeckt ist schon fast Fertig, doch eine Hürde stellt sich mir noch.
Folgendes :
Ich habe eine Client Klasse die alle nötigen Funktionen und Informationen des Sockets beinhalten. Um einzelne Clients anzusprechen habe ich ein Array von dieser Klasse erstellt :
private Client[] clients = new Client[maxClient];
Bei ankommender Verbindung wird nun ein neuer Client erstellt und in dieses Array geschrieben.
clients[connections] = new Client((Socket)socket, this);
Anmerkung : Dieser Vorgang geschieht in einem anderen Thread.
Nur bleiben die Einträge im Array immer NULL.
Somit bekomme ich natürlich immer Errors beim Beenden der Verbindungen
clients[i].Close();
Meine Frage nun warum ? Kann mir da einer Weiterhelfen ?
Hier nochmal der komplette Code:
[SPOILER]
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Net.Sockets;
using System.Windows.Forms;
using System.Net;
using System.Threading;
namespace Remote_Accses_Tool
{
public partial class Client_Form : Form
{
private static int maxClient = 100;
private bool online = false;
private int port = 0;
private Client[] clients = new Client[maxClient];
private TcpListener listener;
private int connections = 0;
public Client_Form()
{
InitializeComponent();
}
private void btnListen_Click(object sender, EventArgs e)
{
if (online)
{
online = false;
for (int i = 0; i <= connections; i++)
{
clients[i].Close();
}
listener.Stop();
btnListen.Text = "Start Listen";
}
else
{
port = Convert.ToInt16(tbxPort.Text);
IPAddress localAddr = IPAddress.Parse("127.0.0.1");
listener = new TcpListener(localAddr, port);
try
{
listener.Start();
online = true;
Thread GettingClients = new Thread(GetClients);
GettingClients.Start();
btnListen.Text = "Stop Listen";
}
catch (Exception)
{
throw;
}
}
}
private void GetClients()
{
while (online)
{
while (online && !listener.Pending())
{
if (!online) { return; } //Gibt sonst eine Exception da die Schleife nicht funktioniert ohne listener
Thread.Sleep(200);
}
Socket socket = listener.AcceptSocket();
Thread StartingClient = new Thread(StartClient);
StartingClient.Start(socket);
Thread.Sleep(100);
connections++;
}
}
private void StartClient(object socket)
{
clients[connections] = new Client((Socket)socket, this);
}
public void updateLog(string Text)
{
tbxLog.Text += Text;
}
}
}
[/SPOILER]
Hallo Dasart
Kannst du auch die Definition von Client posten?
Gruss
Balaban_S
Naja... mal angenommen du hast 2 Clients auf dem Server, lässt aber 100 zu, dann sind natürlich die anderen 98 in deinem Array auf null, weil denen kein Objekt zugewiesen wurde. Also musst du prüfen, ob da überhaupt einer drin ist. Ansonsten schau dir auch mal die foreach Schleife an.
Danke erstmal.
Natürlich bezeihen sich meine aussagen nicht auf das Komplette Array, sondern wirklich auf die einträge.
Sprich ich Lasse einen Client connecten, Aber trotzdem bleibt client[0] null.
Da hilft mir dann die foreach schleife auch nicht sehr viel.
Die definition der Client Klasse ist :
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Net.Sockets;
using System.Net;
using Remote_Accses_Tool;
public class Client
{
private int Status;
private Socket socket = null;
private byte[] buffer = null;
public string IP = "";
private Client_Form formular;
public Client(Socket sock,Client_Form f)
{
socket = sock;
IP = Convert.ToString(socket.LocalEndPoint);
this.formular = f;
sendToLog("Client conntected through: " + Convert.ToString(socket.RemoteEndPoint));
RecieveData();
}
public void RecieveData()
{
while (true)
{
if (socket.Available > 0)
{
buffer = new byte[socket.Available];
//TODO
}
}
}
public void SendData(byte[] sndBuffer)
{
//TODO
}
public void sendToLog(string Text)
{
MethodInvoker listV = delegate
{
formular.updateLog(Text + "\r\n");
};
formular.Invoke(listV);
}
public void Close()
{
socket.Close();
}
}
Hallo Dasart,
connections++;
steht zwar im Code weiter hinten, erfolgt aber in Thread A, wogegen
clients[connections] = new Client((Socket)socket, this);
im frisch gestarteten Thread B erfolgt. Dadurch wird das Inkrementieren in vielen Fällen vor der Zuweisung erfolgen. Dadurch wird beim ersten Durchlauf aber nicht an clients[0], sondern an clients[1] zugewiesen und clients[0] bleibt null.
herbivore
Danke aber daran kann es auch nicht liegen, da wirklich ALLE Elemente im Array null bleiben..
Langsam bin ich echt ratlos o.O
Hallo,
wenn ich's richtig sehe, läuft der Konstruktor der Client-Klasse durch den Aufruf von RecieveData
in eine Endlosschleife. Dadurch bleibt der new
-Aufruf hängen und es wird nix zugewiesen. Da Du dann schon in einem eigenen Thread für den Client bist, fällt's auch sonst nicht weiter auf 🤔
Gruß, MarsStein
Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca
Vielen Vielen Dank.
Wenn ich die Endlosschleife rausnehme funktioniert es. Aber dann habe ich ein Problem weil die Endlosschleife von nöten ist um die Daten in abständen zu empfangen.
Wie könnte ich dieses Problem lösen, hat da einer eine Idee ?
Hallo,
lass die Schleife stehen und nimm den ReceiveData-Aufruf aus dem Konstruktor.
Und dann
private void StartClient(object socket)
{
Client myClient = new Client((Socket)socket, this);
clients[connections] = myClient;
myClient.ReceiveData();
}
Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca
Ahhh o.K das ergibt Sinn. War grade zu aufgeregt um es selber zu merken 😃
Vielen Vielen Dank an MarsStein, der mich aus der schaffenskriese gezogen hat. 😃