Autor Beitrag
WIng2005
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 49



BeitragVerfasst: So 21.03.10 19:16 
Hallo Gemeinde,

ich würde gern mal eure Meinung zu folgender Problematik hören:

Ich schreibe an einer dll, welche ich später nutzen möchte um dynamisch mit mehreren Hosts zu kommunizieren. Diese ca. 5-10 Host sollen dynamisch angesprochen werden können. Hierzu muss ich, wenn ich zu einem neuen Host verbinde, prüfen ob mein Object (TCPClient) a) existiert und wenn ja b) eine offene Verbinung hat. Folgende 2 Versionen habe ich da im Auge:

Version 1:

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:
private TcpClient TC;
.
.
.
public bool connect()
        {
            try
            {
                if (TC.Client == null)
                {
                    TC = new TcpClient();
                }
                else if (TC.Connected)  
                {
                    try
                    {
                        TC.Client.Disconnect(true); //reuse
                    }
                    catch
                    {
                        //do nothing   
                    }
                }
                                
                TC.Connect(ip,port);
                return true;
            }
            catch (Exception ex)
            {
                throw new Exception("Fehler bei der Verbindung zu IP-Adresse "+ip);
            }

        }



oder Version 2:

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:
 

private TcpClient TC;
.
.
.
public bool connect()
        {
            try
            {
                if (TC.Client != null)
                {
                   try
                    {
                        TC.Close();
                    }
                    catch
                    {
                        //do nothing   
                    }
    
                TC = new TcpClient();
                               
                TC.Connect(ip,port);
                return true;
            }
            catch (Exception ex)
            {
                throw new Exception("Fehler bei der Verbindung zu IP-Adresse "+ip);
            }

        }


Welchen der beiden Wege würdet Ihr als sinnvoller bzw. sauberer empfinden? Ich muss sehr oft zur Laufzeit zu untersch. IPs connecten.

Danke für die Hilfe.

Grüße
Steffen
danielf
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1012
Erhaltene Danke: 24

Windows XP
C#, Visual Studio
BeitragVerfasst: Mo 22.03.10 07:40 
Hallo,

"sehr oft" ist sehr relativ - ich verstehe darunter 1000 mal pro Minute ;)

Also Variante 2 macht in meinen Augen keinen Sinn. Warum eine close-Methode aufrufen wenn man nachher eh ein neues Objekt erzeugt? Die Frage stellt sich auch ob du diese Klasse später in mehreren Threads verwenden willst, dann fehlt die Synchronisierung. Auch die TC.Connected gibt nicht den aktuellen, sondern den Status beim letzten Lese-/Schriebprozess aus (siehe MSDN). Um sicherzustellen ob eine Verbindung wirklich noch aktiv ist, musst du etwas Senden (siehe dazu auch MSDN).

Ich verstehe nicht genau die Optimierung dahinter.

Wenn ich Verbindung zu vielen Hosts aufbauen muss, etwas verarbeiten muss, dann kenne ich den Status jeder Verbindung. D.h. ich weiß dass sie offen oder geschlossen ist, das Objekt instantiiert oder nicht ist etc. Warum also so ein Terz?

Gruß Daniel
WIng2005 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 49



BeitragVerfasst: Mo 22.03.10 22:50 
Hallo und danke für die Antwort,

also: ich möchte sicherstellen, dass vor jedem Verbinden zu einr IP alle vorherigen Verbindungen getrennt sind.
Habe jetzt mal folgendes versucht:

ausblenden 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:
public bool connect() 
        {
            try
            {
                if (TC.Client == null)
                {
                    TC = new TcpClient();
                }
                else if (TC.Client.Connected)
                    try
                    {
                        TC.Client.Disconnect(false);
                    }
                    catch 
                    {
                        throw new Exception("Fehler beim disconnecten");
                    }
                TC.Connect(ip, port);
                return true;
            }

            catch (Exception ex)
            {
                throw new Exception("Fehler bei der Verbindung zu IP-Adresse "+ip+"  "+ex);
            }

        }


Jedoch bekomme ich beim 2. Durchlauf die Meldung:
"Fehler bei der Verbindung zu IP-Adresse 192.168.1.60 System.Net.Sockets.SocketException: Eine Verbindungsanforderung bezog sich auf einen bereits verbundenen Socket"
Die Frage ist also, wie ich den Socket schließen kann (im Beispiel wurde TC.Client.Disconnect(false) abgearbeitet, die Meldung kam trotzdem)

Die Funktion von TC.connected schaue ich mir nochmal an (danke für den Hinweis)

Danke für die Hilfe
MFG
Steffen
danielf
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1012
Erhaltene Danke: 24

Windows XP
C#, Visual Studio
BeitragVerfasst: Mo 22.03.10 23:01 
Was machst du mit der Disconnect Methode? Woher hast du die den her?

Bei MSDN steht
Zitat:
PlatformNotSupportedException This method requires Windows 2000 or earlier, or the exception will be thrown.


Ich weiß zwar nicht genau was das heißt "earlier", aber ich könnte mir vorstellen, dass es nur win200, win98 und win95 funktioniert. Warhscheinlich brauchst du deshalb auch dein try-catch block?

Mach doch einfach wie bei MSDN und in allen Beispielen beschrieben TC.Close() ...
WIng2005 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 49



BeitragVerfasst: Mo 22.03.10 23:13 
Hallo,

aber dann hätten wir ja doch Variante 2.
So habe ich es mal getestet, was auch funktioniert:

ausblenden 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:
 public bool connect()         {
            try
            {
                if (TC.Client == null)
                {
                    TC = new TcpClient();
                }
                else if (TC.Connected)
                {
                    try
                    { 
                        TC.Close();
                        TC = new TcpClient();
                    }
                    catch
                    {
                        throw new Exception("Fehler beim Disconnecten von "+ip);
                    }
                }
                TC.Connect(ip, port);
                return true;
            }

            catch (Exception ex)
            {
                throw new Exception("Fehler bei der Verbindung zu IP-Adresse "+ip+"  "+ex);
            }

        }



Um noch die Frage zur Häufigkeit zu beantworten:
Das ganze soll eine Eisenbahnsteuerung werden (erstmal nur zur Fahrstraßenbildung). Die Anzahl der Wechsel des Hosts wird sich in Grenzen halten, nicht jedoch die Geschwindigkeit. D.h. ich wechsel nicht oft, jedoch wenn, dann kurzeitig mehrfach... (ich würde diesen Satz jetzt nicht verstehen...ich hoffe mal du kannst mir folgen)

MFG
Steffen
WIng2005 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 49



BeitragVerfasst: Mo 22.03.10 23:26 
Mmmh, nur laut msdn bewirkt das close : Verwirft diese TcpClient-Instanz, ohne die zugrunde liegende Verbindung zu schließen.

Hilft mir also auch nicht weiter.

MFG
Steffen
danielf
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1012
Erhaltene Danke: 24

Windows XP
C#, Visual Studio
BeitragVerfasst: Mo 22.03.10 23:31 
Ich meinte, dass die Variante so wie sie da stand keinen Sinn macht. Dachte es ging um die If-Else Zweige. Die Methoden hatte ich mir gar nicht genau angeschaut :o

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:
public bool Connect()
{
   if (CheckConnection(TC)
   {
      // bestehende Verbindung beenden 
      TC.Close();
      TC = null;
   }

   // Client instanziieren
   TC = new TcpClient();
   
   TC.Connect(ip, port)

   return TC.Connected;
}

public bool CheckConnection(TcpClient client)
{
   if (!client.Connected)
   {
      return false;
   }

   // try to send something (renew status)
   // http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.connected.aspx
   // This is how you can determine whether a socket is still connected.
   bool blockingState = client.Blocking;
  try
  {
     byte [] tmp = new byte[1];

     client.Blocking = false;
     client.Send(tmp, 00);
     Console.WriteLine("Connected!");
   }
   catch (SocketException e) 
   {
     // 10035 == WSAEWOULDBLOCK
     if (!e.NativeErrorCode.Equals(10035))
     {
        return false;
     }
   }
   finally
   {
      client.Blocking = blockingState;
   }

   return client.Connected;
}


}
WIng2005 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 49



BeitragVerfasst: Mo 22.03.10 23:56 
Dank dir für deine Mühe.....muss mir dass morgen mal in Ruhe anschauen, bringt heute nix mehr..

MFG
Steffen
WIng2005 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 49



BeitragVerfasst: So 28.03.10 14:27 
Sooo, nun will ich doch nocheinmal ein Feedback geben.
Habe das ganze mal getestet, wenngleich ich erstmal auf darauf verzichtet habe, mich näher mit der CheckConnection-Methode zu befassen (wenn man nur mehr Zeit hätte...). Das TC.close ist mir noch ein wenig schleierhaft, da die msdn sagt, dass die bestehenden Verbindungen offen bleiben. Werde mir auf Jeden Fall das ganze nocheinmal genauer ansehen müssen, komme nur irgendwie zu nichts.... Ich danke Dir auf jeden Fall für deine Hilfe!!

MFG
Steffen