Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
Array-Element bleibt trotz Zuweisung eines Objekts null
Dasart
myCSharp.de - Member



Dabei seit:
Beiträge: 25

Themenstarter:

Array-Element bleibt trotz Zuweisung eines Objekts null

beantworten | zitieren | melden

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]
private Nachricht | Beiträge des Benutzers
Balaban_S
myCSharp.de - Member

Avatar #avatar-3199.jpg


Dabei seit:
Beiträge: 196
Herkunft: Zürich/Schweiz

beantworten | zitieren | melden

Hallo Dasart

Kannst du auch die Definition von Client posten?

Gruss
Balaban_S
private Nachricht | Beiträge des Benutzers
Corpsegrinder
myCSharp.de - Member



Dabei seit:
Beiträge: 416

beantworten | zitieren | melden

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.
private Nachricht | Beiträge des Benutzers
Dasart
myCSharp.de - Member



Dabei seit:
Beiträge: 25

Themenstarter:

beantworten | zitieren | melden

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();
    }
}
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 52329
Herkunft: Berlin

beantworten | zitieren | melden

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
private Nachricht | Beiträge des Benutzers
Dasart
myCSharp.de - Member



Dabei seit:
Beiträge: 25

Themenstarter:

beantworten | zitieren | melden

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



Langsam bin ich echt ratlos o.O
private Nachricht | Beiträge des Benutzers
MarsStein
myCSharp.de - Experte

Avatar #avatar-3191.gif


Dabei seit:
Beiträge: 3430
Herkunft: Trier -> München

beantworten | zitieren | melden

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
private Nachricht | Beiträge des Benutzers
Dasart
myCSharp.de - Member



Dabei seit:
Beiträge: 25

Themenstarter:

beantworten | zitieren | melden

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 ?
private Nachricht | Beiträge des Benutzers
MarsStein
myCSharp.de - Experte

Avatar #avatar-3191.gif


Dabei seit:
Beiträge: 3430
Herkunft: Trier -> München

beantworten | zitieren | melden

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
private Nachricht | Beiträge des Benutzers
Dasart
myCSharp.de - Member



Dabei seit:
Beiträge: 25

Themenstarter:

beantworten | zitieren | melden

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. :)
private Nachricht | Beiträge des Benutzers