Autor Beitrag
Dasarto
Hält's aus hier
Beiträge: 2



BeitragVerfasst: Mi 22.09.10 16:50 
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 :
ausblenden C#-Quelltext
1:
private Client[] clients = new Client[maxClient];					


Bei ankommender Verbindung wird nun ein neuer Client erstellt und in dieses Array geschrieben.

ausblenden C#-Quelltext
1:
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
ausblenden C#-Quelltext
1:
clients[i].Close();					


Meine Frage nun warum ? Kann mir da einer Weiterhelfen ?


Hier nochmal der komplette Code:
ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
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;
        }
    }
}


Und Hier die Client Klasse
ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
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();
    }
}
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4798
Erhaltene Danke: 1059

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Mi 22.09.10 18:40 
Hinweis für andere Helfer: Crosspost, s.a. www.mycsharp.de/wbb2...d.php?threadid=89039

Hallo Desarto,

du hast dein Programm aber immer noch nicht entsprechend herbivore's Hinweis umgeschrieben.
Thread-Programmierung ist keine einfache Sache (Thread.Sleep hilft da nur unzureichend)!

Hast du denn mal mit dem Debugger jede einzelne Zeile überprüft?
Wie sieht denn das Array nach der Zuweisung in 'StartClient' aus?
Dasarto Threadstarter
Hält's aus hier
Beiträge: 2



BeitragVerfasst: Mi 22.09.10 18:51 
Das ist zwar ein Problem was ich noch in angriff nehmen muss, aber es hat nix mit dem Array zu tuhen, denn wie gesargt bleibt das Komplette Array null.

Wenn es bei den Threads liegen würde währe ja mindestens clients[1] gefüllt, ist aber nicht der Fall.
Ich habe jetzt jede einzelne Zeile debuggt und komme einfach nicht weiter.

Nach der Zuweisung bleiben alle Elemente null.

Mal ne frage ist Crossposting unzulässig, weil du das so hervorhebst ? Wenn ja entschuldige ich mich dafür..

EDIT:\\
Das Problem ist nun dank einem findigen User gelöst
Danke trotzdem an alle :)
Trashkid2000
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 561
Erhaltene Danke: 137



BeitragVerfasst: Mi 22.09.10 21:06 
Hi,

Crossposts sind zwar in DIESEM Forum erlaubt, trotzdem aber immer nicht so schön, da man als Helfer immer erst im anderen Forum schaun muss, wie da der Stand der Dinge (oder des Problems) ist.

Habe Deinen Code mal probiert und auch mal debuggt. Dabei habe ich bemerkt, dass Deine Prozedur
ausblenden C#-Quelltext
1:
RecieveData();					
(müsste es nicht "ReceiveData"heißen) in der Klasse Clients einen Fehler schmeisst. Oder besser gesagt, keinen Fehler schmeisst, sondern einfach abbricht. Da die Funktion im Konstruktor der Klasse Clients aufgerufen wird, wird also auch nichts in das Array hinzugefüht. Da es halt schon beim instanziiren abbricht. Was da aber genau der Fehler ist, weiss ich ehrlich gesagt nicht :oops:

Ansonsten sind mir noch ein paar Dinge aufgefallen (habe mir den Thread im anderen Forum nicht angesehen):
Warum ein
ausblenden C#-Quelltext
1:
Client[] clients					
und nicht eine
ausblenden C#-Quelltext
1:
List<Client> clients					
Wäre für diesen Zweck wirklich besser, da Du die Verbindungen auf 100 festlegst. Bei ein er List<> könntest Du die Elemente hinzufügen, und könntest dann beim offline gehen die Anzahl abfragen. Und wenn Du Dich doch für ein Arry entscheidest, prüfe vor dem Aufruf von
ausblenden C#-Quelltext
1:
clients[i].Close();					
auf null!! Das
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
while (online && !listener.Pending())
{
  if (!online) 
  {                    //Gibt sonst eine Exception da die Schleife nicht funktioniert ohne listener
    Thread.Sleep(200);
  }
kannst Du Dir auch schenken, da
ausblenden C#-Quelltext
1:
Socket socket = listener.AcceptSocket();					
solange wartet, bis sich ein Client verbindet.

Ansonsten solltest Du noch die Anzahl der Connections
ausblenden C#-Quelltext
1:
connections++;					
in die Methode
ausblenden C#-Quelltext
1:
StartClient(object socket)					
packen, da durch das Thread.Sleep() der Counter schon vor Ausführung der Methode hoch gesetzt wird.

Und ganz zum Schluss: ich habe das Gefühl, als ob der Process "GettingClients" endlos lauft. Jedenfalls trat beim beenden des Programs der Fall auf, dass die Form total hing. Habe mal dem Thread beim offline gehen gekillt, und dann war das Verhalten okay.


Hoffe, ich konnte ein wenig weiterhelfen,

Marko

Für diesen Beitrag haben gedankt: Dasarto