Laden...

Array-Element bleibt trotz Zuweisung eines Objekts null

Erstellt von Dasart vor 13 Jahren Letzter Beitrag vor 13 Jahren 2.358 Views
D
Dasart Themenstarter:in
25 Beiträge seit 2010
vor 13 Jahren
Array-Element bleibt trotz Zuweisung eines Objekts null

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]

194 Beiträge seit 2006
vor 13 Jahren

Hallo Dasart

Kannst du auch die Definition von Client posten?

Gruss
Balaban_S

C
401 Beiträge seit 2007
vor 13 Jahren

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.

D
Dasart Themenstarter:in
25 Beiträge seit 2010
vor 13 Jahren

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();
    }
}

49.485 Beiträge seit 2005
vor 13 Jahren

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

D
Dasart Themenstarter:in
25 Beiträge seit 2010
vor 13 Jahren

Danke aber daran kann es auch nicht liegen, da wirklich ALLE Elemente im Array null bleiben..

Langsam bin ich echt ratlos o.O

3.170 Beiträge seit 2006
vor 13 Jahren

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

D
Dasart Themenstarter:in
25 Beiträge seit 2010
vor 13 Jahren

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 ?

3.170 Beiträge seit 2006
vor 13 Jahren

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

D
Dasart Themenstarter:in
25 Beiträge seit 2010
vor 13 Jahren

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. 😃