Autor Beitrag
JackLuhn
Hält's aus hier
Beiträge: 5



BeitragVerfasst: Sa 04.08.12 07:03 
Hallo Zusammen,

Ich habe ein Kleines Problem.

Ich Wollte ein ein Socket aufbauen das hat auch alles geklappt er Aktzeptiert die Verbindung.
Aber wenn ich jetzt Über ein Consolen Commando die die verbindungen Trennen will bekomme ich ein Hashtable.Enumerator: snapshot out of sync. Fehler.

Entwicklungs Infos:
Betriebssystem: Linux Mint 12 (Lisa)
Editor/Compiler: MonoDevelop

Bilder:
user defined image

Code der Class:
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:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
using System;
using System.Linq;
using System.Text;
using System.Threading;
using System.Collections;
using System.Collections.Generic;

namespace SocketServer.system.net
{
    class SocketConnectionHelper
    {
        private static int BannedIPcount;
        private static Hashtable BannedIPs = new Hashtable();
        private static Hashtable Connections = new Hashtable();
        private static Thread Checker = new Thread(new ThreadStart(CheckSockets));

        internal static void Init()
        {
            Checker.Start();
        }

        public static bool IsBanned(string IP)
        {
            if (BannedIPs.ContainsKey(IP) == true)
      {
                return true;
      }
            else
            {
                string banReason/* = userManager.getBanReason(IP)*/;//not coded yet
        banReason = "";
                if (banReason != "")
                {
                    BannedIPs.Add(IP, BannedIPcount);
                    BannedIPcount++;
                    return true;
                }
                else
                {
                    return false;
                }
            }
        }
        private static void CheckSockets()
        {
            while (SocketServer.MainClass.running)
            {
        
                Hashtable TMP = Connections;
                foreach (socketConnection EndPoint in TMP.Values)
                {
                    if (!EndPoint.IsActive)
          {
                        EndPoint.Disconnect();
          }
                }
        TMP = null;
        GC.Collect();
                Thread.Sleep(10000);
            }
        }
        public static void DisonnectSockets()
        {
      try
      {
            Hashtable TMP = Connections;
              foreach (socketConnection EndPoint in TMP.Values)
              {
                  EndPoint.Disconnect();
              }
        TMP = null;
        GC.Collect();
      }
      catch(Exception error)
      {
                Console.WriteLine("Ein Fehler ist Aufgetretten: " + error.Message + "");
        Console.WriteLine("Details: " + error.ToString() + "");
      }
        }
        internal static void AddConnection(socketConnection Endpoint, int ConnectionID)
        {
      try
      {
              if (Connections.ContainsValue(ConnectionID))
        {
                  Connections.Remove(ConnectionID);
        }
              Connections.Add(ConnectionID, Endpoint);
      }
      catch(Exception error)
      {
                Console.WriteLine("Ein Fehler ist Aufgetretten: " + error.Message + "");
        Console.WriteLine("Details: " + error.ToString() + "");
      }
        }
    
        internal static void RemoveConnection(int ID)
        {
      try
      {
              if (Connections.ContainsValue(ID) || Connections.ContainsKey(ID))
        {
                  Connections.Remove(ID);
        }
      }
      catch(Exception error)
      {
                Console.WriteLine("Ein Fehler ist Aufgetretten: " + error.Message + "");
        Console.WriteLine("Details: " + error.ToString() + "");
      }
        }
    }
}


Brauche dringen Hilfe,
Schon mal Danke im Vorraus.

Wenn ihr Mehr Informationen braucht Sagt bescheidt. Aber Glaube mal das das genügend infos sind :)

Mit Freundlichen Grüßen JackLuhn
Christoph1972
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 690
Erhaltene Danke: 16


VS2015 Pro / C# & VB.Net
BeitragVerfasst: Sa 04.08.12 09:09 
Hi,

hast du die Fehlermeldung mal bei google eingegeben? Google kennt scheinbar einiges zu der Exception. Da ich mich mit Sockets und Mono, Linux nicht auskenne habe ich mir die Ergebnisse nicht im detail angeschaut. Aber es ist bestimmt etwas für dich dabei.

_________________
Gruß
Christoph
JackLuhn Threadstarter
Hält's aus hier
Beiträge: 5



BeitragVerfasst: Sa 04.08.12 09:25 
Ja habe ich.
Aber Google konnte mir nur das sagen was ich auch gemacht habe.

Denn bei Google wurde das Problem oft im Zusammenhang mit Hashtable die wärend der Bearbeitung verändert werden.
Da ich die Hashtable aber Klone (In einen Andere variable Kopiere) und die Änderungen nicht an der Geklonten Version ändere sondern in der Original Version kann es ja nicht da dran liegen.

Die Hashtable hat übrigens die function die Aktiven Verbindungen zu Speichern und so Später Bevor der Server Schliesst An Alle User eine Nachricht zu senden das der Server Schliesst und dann Die User zu Disconnecten.
Zudem wird dann durch Thread überprüft ob eine Verbindung in Aktive ist und sie dann Versuchen zu Disconnecten oder zu Löschen.
Es soll auch noch dazu dienen um zu Überprüfen ob eine IP Addresse Mehrfach Verbunden ist.

Ich Hoffe mal einer von euch der Mehr weiss als ich Kann mir Helfen.

Mit Vielen Grüßen JackLuhn
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: Sa 04.08.12 10:20 
Hallo JackLuhn :welcome:

ich sehe nirgendswo in deinem Code, wo du die Hashtable klonst.
Die Zuweisung Hashtable TMP = Connections bedeutet nur, daß du der Hashtable eine weitere Referenz hinzufügst (d.h. einen anderen Variablennamen für das gleiche Objekt gibst).

Und bei Threadprogrammierung mußt du immer gemeinsam-genutzte Objekte synchronisieren. Gestern erst hatte ich einen Tipp für einen Multithreading-Artikel unter www.entwickler-ecke.....php?p=666284#666284 gegeben.
JackLuhn Threadstarter
Hält's aus hier
Beiträge: 5



BeitragVerfasst: Sa 04.08.12 10:55 
Aber in dem Sinne ist es doch schon Kopieren oder?

Weil wenn die hashtable connections in die variable TMP kopiert wird, und sich Später dann die hashtable connections ändert
sind die doch nicht mehr gleich?

Und es soll ja auch kein Multithread werden da function DisonnectSockets() eine function ist die aufgerufen wird wenn sich der server schliessen soll und alle verbindungen Schliessen soll.

Das einzigste Thread in der Klasse ist ja CheckSockets() die alle 10Sekunden Überprüft ob die Verbindungen noch Aktive ist.

Oder habe ich da was Falsch verstanden.
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: Sa 04.08.12 11:32 
Sorry, dir das zu schreiben, aber dir fehlen (anscheinend) noch einige Grundlagen (Objekte, Referenzen, Wertetypen, Variablen, ...) von C# (bzw. .NET).
Socket- und Threadprogrammierung hat sehr viele Fallstricke, und dazu muß man genau wissen, was jede einzelne Anweisung macht (sonst verhält sich das Programm anders als man es evtl. erwartet).
Nimm dir zumindestens die Zeit und lies dir den Artikel durch - besonders zum Thema Threadsynchronisierung!

P.S. Um doch direkt auf deine Frage zu antworten: NEIN ;-)
Wie lange lernst du denn schon C# und mit welcher Lektüre (Buch, Tutorial, ...)?
JackLuhn Threadstarter
Hält's aus hier
Beiträge: 5



BeitragVerfasst: Sa 04.08.12 11:59 
Ich habe mir zum Großten teil alles Selber beigebracht und Arbeite in dem Bereich seit ca. 1 Jahr. Seit kurzen Da mein Laptop kapput ist, Auf Linux (MonoDevelop).
Zum teil Bringt mir ab und zu ein Freund Etwas bei. Aber Selten.

Und kein problem ich komme mit Kritik gut klar, denn dadurch kann man sich verbessern.
Ich werde mir das Thema mal angucken und versuchen umzusetzten.
JackLuhn Threadstarter
Hält's aus hier
Beiträge: 5



BeitragVerfasst: So 05.08.12 21:00 
So habe mir dein Post mal angeguckt.
Habe mir auch ein paar andere Themen in anderen Forums angeguckt.

Und so wie ich das verstanden habe soll Das Theared das Checkt od die Sockets noch verbunden sind auf das (Wenn gestartet) Thread warten das Alle Verbindungen Schliesst.

Habe es dann auch so in die Tat umgesetzte. Habe ein Neues Thread geschrieben und dann im Checkr Theard abgefragt ob Close Thread lauft und wenn ja Soll es Drauf warten bis es Zu ende ist.
Dem Socket wird soger mitgeteilt das wenn er in der Zeit keine Verbindungen Zulassen soll;

So Jetzt Klappt alles Einwandfrei bis aber der Fehler kommt immer noch ;(

Glaube mal das ich was Falsch verstanden habe.

Hier mal den 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:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
using System;
using System.Linq;
using System.Text;
using System.Threading;
using System.Collections;
using System.Collections.Generic;

namespace SocketServer.system.net
{
    class SocketConnectionHelper
    {
        private static int BannedIPcount;
        private static Hashtable BannedIPs = new Hashtable();
        private static Hashtable Connections = new Hashtable();
        private static Thread Checker = new Thread(new ThreadStart(CheckSockets));
        private static Thread end = new Thread(new ThreadStart(DisSockets));

        internal static void Init()
        {
          Console.WriteLine("[Thread] SocketConnectionHelper Start");
            Checker.Start();
        }

        public static bool IsBanned(string IP)//prüft beim verbindungs versuch ob die IP gebannt wurde
        {
            if (BannedIPs.ContainsKey(IP) == true)
      {
                return true;
      }
            else
            {
                string banReason/* = userManager.getBanReason(IP)*/;//not coded yet
        banReason = "";
                if (banReason != "")
                {
                    BannedIPs.Add(IP, BannedIPcount);
                    BannedIPcount++;
                    return true;
                }
                else
                {
                    return false;
                }
            }
        }
        private static void CheckSockets()//prüft alle alle 10sekunden ob die Verbindungen noch aktive sind.
        {
            while (SocketServer.MainClass.running)//wird auf false gesetzt wenn server beendet wird
            {
        try
        {
          if(end.IsAlive)
          {
            end.Join();
          }
                  Hashtable TMP = Connections;
                  foreach (socketConnection EndPoint in TMP.Values)
                  {
                      if (!EndPoint.IsActive)
            {
                          EndPoint.Disconnect();
              Console.WriteLine("Disconnect: " + EndPoint.id + "");
            }
                  }
          TMP = null;
          GC.Collect();
                  Console.WriteLine("[Thread] Socket Check");
        }
        catch(Exception error)
        {
                  Console.WriteLine("Ein Fehler ist Aufgetretten: " + error.Message + "");
          Console.WriteLine("Details: " + error.ToString() + "");
        }
                Thread.Sleep(1000);//Diente zum test der join fuction von Checker Thread
            }
        }
    private static void DisSockets()
        {
      try
      {
        SocketServer.MainClass.iSocket.AcceptConnections(false);
              foreach (socketConnection EndPoint in Connections.Values)
              {
                  EndPoint.Disconnect();
              }
        GC.Collect();
                Thread.Sleep(10000);
              Console.WriteLine("[Thread] Sockets Disconnect");
      }
      catch(Exception error)
      {
                Console.WriteLine("Ein Fehler ist Aufgetretten: " + error.Message + "");
        Console.WriteLine("Details: " + error.ToString() + "");
      }
      SocketServer.MainClass.iSocket.AcceptConnections(true);
    }
        public static void DisonnectSockets()//hier drüber wird das Thread Gestartet
//aufgerufen wird es wenn der server beendet werden soll
        {
      try
      {
        end = new Thread(new ThreadStart(DisSockets));
              end.Start();
        end.Join();
        end.Abort();
        end = new Thread(new ThreadStart(DisSockets));//neu setzten ansonsten bekomme ich ein fehler
      }
      catch(Exception error)
      {
                Console.WriteLine("Ein Fehler ist Aufgetretten: " + error.Message + "");
        Console.WriteLine("Details: " + error.ToString() + "");
      }
        }
        internal static void AddConnection(socketConnection Endpoint, int ConnectionID)
        {
      try
      {
              if (Connections.ContainsValue(ConnectionID))
        {
          
                  Connections.Remove(ConnectionID);
        }
              Connections.Add(ConnectionID, Endpoint);
      }
      catch(Exception error)
      {
                Console.WriteLine("Ein Fehler ist Aufgetretten: " + error.Message + "");
        Console.WriteLine("Details: " + error.ToString() + "");
      }
        }
    
        internal static void RemoveConnection(int ID)
        {
      try
      {
              if (Connections.ContainsValue(ID) || Connections.ContainsKey(ID))
        {
                  Connections.Remove(ID);
        }
      }
      catch(Exception error)
      {
                Console.WriteLine("Ein Fehler ist Aufgetretten: " + error.Message + "");
        Console.WriteLine("Details: " + error.ToString() + "");
      }
        }
    }
}