vb@rchiv
VB Classic
VB.NET
ADO.NET
VBA
C#
Erstellen von dynamischen Kontextmen?s - wann immer Sie sie brauchen!  
 vb@rchiv Quick-Search: Suche startenErweiterte Suche starten   Impressum  | Datenschutz  | vb@rchiv CD Vol.6  | Shop Copyright ©2000-2024
 
zurück

 Sie sind aktuell nicht angemeldet.Funktionen: Einloggen  |  Neu registrieren  |  Suchen

VB.NET - Ein- und Umsteiger
Re: Probleme mit TCP 
Autor: Preisser
Datum: 22.06.11 18:59

Hallo,

vielleicht solltest du auch im Server die aufgetretenen Exceptions nicht einfach ignorieren lassen, sondern eine Ausgabe mit einbauen, wenn eine Exception auftritt (Art der Exception, Fehlermeldung und Stacktrace).

Bist du dir auch sicher, dass du den SyncLock richtig verwendest? Beispielsweise in ListenToConnection() siehst du zuerst in der Liste nach, ob der Client schon vorhanden ist, machst dann noch was anderes und fügst den Client dann hinzu. Da der Codeblock eine logische Einheit/Transaktion ist, muss entsprechend ein Synclock von der For Each-Schleife bis zu PClients.Add(c) gehen, und nicht z.b. zwei getrennte SyncLocks (einer bei der For Each-Schleife und einer bei dem PClients.Add). Sonst könnte es ja passieren, dass ein Client trotzdem doppelt drin ist, wenn die Threads grade ungünstig laufen.

Übrigens liefert StreamReader.ReadLine() null (Nothing), wenn das Streamende erreicht ist. Es wäre besser, nach den Rückgabewert auf Nothing zu testen, anstatt darauf zu vertrauen, dass bei einem späteren Zugriff auf den String eine NullReferenceException geworfen wird.

Beitrag wurde zuletzt am 22.06.11 um 19:08:31 editiert.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Probleme mit TCP 
Autor: Daddaaff
Datum: 22.06.11 16:34

Hallo, ich bin mit meiner Server-Client_Anwendung schon einiges weiter, jedoch plagen mich manche Kleinigkeiten wofür ich einfach keine Ursache finden kann. Machmal entstehen doppelte Verbindungen, es passieren unerklärlich Verbindungsabbrüche, wonach ein erneutes Verbind erst nach dem Neustart der Anwendungen möglich ist und manchmal bleibt die Anwendung einfach stehen. Kann sich das mal einer ansehen, ob ich da wo einen Dankfehler habe?

Start des Servers:
Try
            PServer = New TcpListener(PIPendpoint)
            PServer.Start()
            While True
                PClient = New TcpClient
                Dim c As New Connection
                TXT("Warte auf neue Verbindung")
                PClient = PServer.AcceptTcpClient
                c.stream = PClient.GetStream
                c.streamw = New StreamWriter(c.stream)
                c.streamr = New StreamReader(c.stream)
                Dim t As New Threading.Thread(AddressOf ListenToConnection)
                t.Start(c)                
            End While
        Catch ex As Exception
        End Try
Hier die ListenToConnection():
Dim Info As String
        Dim Infos() As String
        Try
            c.streamw.WriteLine(ID & "||" & PConnectable)
            c.streamw.Flush()
            Info = c.streamr.ReadLine
            Infos = Split(Info, "||")
            c.ClientID = Infos(0)
            For Each cl As Connection In PClients 'Um doppelte Verbindungen zu 
            ' vermeiden
                Dim cIP() As String
                cIP = Split(cl.ClientID.ToString, ":")
                If cIP(0) = Infos(0) Then
                    TXT(cIP(0) & " bereits verbunden")
                    c.stream.Close()
                    Exit Sub
                Else
                    TXT(cIP(0) & " noch nicht verbunden")
                End If
            Next
            c.ClientIP = PClient.Client.RemoteEndPoint.ToString
            c.Servant = Infos(1)
            PClients.Add(c)
            TXT("Neuer Client: " & c.ClientID)
            Dim SplitMSG() As String
            Dim NewTTL As Integer
            Dim FullMSG As String
            While True
                FullMSG = c.streamr.ReadLine
               MSG(FullMSG)' Da passieren alle möglichen Sachen, jedoch nicht 
               ' von belangen
            End While
        Catch
            Try
                PClients.Remove(c)
                TXT(c.ClientID & " hat die Verbindung abgebrochen")
            Catch ex As Exception
            End Try
        End Try
So Connecte Ich:
Function Connect(ByVal IP As String)
        Try            
            For Each c As Connection In PClients 'Um doppelte Verbindungen zu 
            ' vermeiden
                Dim cIP() As String
                cIP = Split(c.ClientIP.ToString, ":")
                If cIP(0) = IP Then
                    TXT(cIP(0) & " bereits verbunden")
                    Return False
                    Exit Function
                Else
                    TXT(cIP(0) & " noch nicht verbunden")
                End If
            Next
            TXT("Verbinde zu " & IP)
            PClient = New TcpClient
            PClient.Connect(IP, PPort)
            If PClient.Connected Then
                Dim c As New Connection
                c.stream = PClient.GetStream
                c.streamw = New StreamWriter(c.stream)
                c.streamr = New StreamReader(c.stream)
                Dim t As New Threading.Thread(AddressOf ListenToConnection)
                t.Start(c)               
            End If
        Catch ex As Exception
            TXT("EX: Verbindung konnte nicht hergestellt werden")
            Return False
        End Try
        Return True
    End Function
Wo könnte hier ein Fehler liegen?

Vielen Dank für eure Hilfe!
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Probleme mit TCP 
Autor: Code_mancer
Datum: 22.06.11 16:40

Beim schnellen drüber sehen vermisse ich sowas wie ein synclock o.ä.

Das heisst: es könnte sein, dass zwei von dir gestartete threads gleichzeitig auf die selben Objekte zugreifen und das ergibt gerne mal pures Chaos.

--------------------

Ich habe keine besondere Begabung, sondern bin nur leidenschaftlich neugierig.
- Albert Einstein

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Probleme mit TCP 
Autor: Daddaaff
Datum: 22.06.11 16:59

So etwas?
SyncLock PClients
                PClients.Add(c) ' und fügen sie der liste der clients hinzu.
            End SyncLock
Wo würde ich das noch benötigen, ausser bei Arbeiten mit der Liste?
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Probleme mit TCP 
Autor: Code_mancer
Datum: 22.06.11 17:29

Allgemein gesagt überall da, wo du Zeiger veränderst. Damit bist du auf der sicheren, wenn auch ggf. langsameren Seite. Sorg' erstmal einfach dafür, dass die gesamte ListenToConnection nur immer von einem Thread gleichzeitig angesteuert werden kann.

SyncLock ist übrigens nicht die einzige Möglichkeit, das zu behandeln. Ich habe dir damit nur eine Richtung aufzeigen wollen. Recherchier mal bei Gelegenheit, was es da noch gibt

--------------------

Ich habe keine besondere Begabung, sondern bin nur leidenschaftlich neugierig.
- Albert Einstein

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Probleme mit TCP 
Autor: Daddaaff
Datum: 22.06.11 17:33

Ok, Danke für die Hilfe.

Was macht eigentlich ein Thread, wenn er versucht auf eine Datei zuzugreifen, die mit SyncLock gesperrt ist? Wartet er einfach bis sie wieder frei ist?
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Probleme mit TCP 
Autor: Code_mancer
Datum: 22.06.11 17:41

In die Richtung habe ich noch nicht mit Threads gearbeitet, aber ich denke, da verläuft es ähnlich. Schließlich manipulierst du ja nicht direkt die Datei, sondern gibst immer erst einem Objekt den Auftrag, diese Datei zu manipulieren. Da SyncLock den Zugriff auf das Objekt unterbindet, müsste ein weiterer Thread "vorm" Lock warten, bis der bereits arbeitende Thread den Lock-Bereich verlassen hat.

--------------------

Ich habe keine besondere Begabung, sondern bin nur leidenschaftlich neugierig.
- Albert Einstein

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Probleme mit TCP 
Autor: Daddaaff
Datum: 22.06.11 17:56

Ich habe nun alle Arbeiten mit der Liste über SyncLock gesichert, jedoch bestehen meine Probleme weiterhin! Vorallem das ich vor einem Erneuten verbinden die Anwendungen erst neu starten muss. Ich weis jedoch nicht ob es am Server oder am Client liegt.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Probleme mit TCP 
Autor: Daddaaff
Datum: 22.06.11 19:54

Normalerweise behandle ich die Exeptions. So bin ich auch darauf gekmmen, dass manchmal beim Senden don Daten ein fehler auftritt, unzwar das die Gegenstelle di3e Verbindung beendet hat. Aber ich heb eben bisher einen Verbindungsabbruch durch eine Exeption erkannt. Hoffentlich erledigt sich das, wenn ich auf nothing prüfe.

Ok, bie ListenToConnection habe ich nun das SyncLock auf den ganzen block ausgeweitet. Bei Connect allerding würde das bedeuten das die Liste sehr lange gespert ist, da es mitunter - vorallem bei nicht zustande kommender Verbindung - mehrer Sekunden dauert.

Wenn ich nun mit StreamReader.ReadLine() = Nothing einen Verbindungsabbruch erkannt habe, wie sollte ich die Verbindung ordentlich schließen? Ich habe zuvor gar nichts unternommen und versuche nun gerade
Try
            c.stream.Close()
            c.Client.Client.Close()
            TXT(c.ClientID & " hat die Verbindung abgebrochen")
            PClients.Remove(c)
        Catch ex As Exception
 
        End Try
Das Try ist dafür gedacht, dass es ja sein kann, das ein Client noch gar nicht in der Liste war und somit der Versuch ihn daraus zu löschen eine Exeption verursacht. Liege ich damit richtig?

Hier übrigens meine Connection:
Structure Connection
        Dim stream As NetworkStream
        Dim streamw As StreamWriter
        Dim streamr As StreamReader
        Dim ClientID As String 'Identifikation des clients.
        Dim ClientIP As String 'IP des CLients
        Dim Client As TcpClient
    End Structure


Beitrag wurde zuletzt am 22.06.11 um 19:55:28 editiert.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Probleme mit TCP 
Autor: Preisser
Datum: 22.06.11 20:21

Hallo,

wie meinst du das, mit Connect()? Du müsstest halt eine Art Verbindung eintragen in die Liste (also hier z.B. ein Connection-Element), und dir merken, dass diese Verbindung noch nicht hergestellt wurde o. ä. Dann musst du nicht so lange synchronisieren.

Es stimmt schon, dass bei einem Verbindungsabbruch (also wenn die Verbindung nicht ordnungsgemäß geschlossen wurde) eine Exception aufritt, aber wenn die Verbindung auf normalen Weg geschlossen wird, sollte keine auftreten; stattdessem müsste der Reader das Erreichen des Streamendes melden (mit Rückgabewert Nothing bei ReadLine()).

Wenn du aus einer Liste ein Element entfernst, das nicht vorhanden ist, gibt die .Remove()-Methode false zurück, ohne eine Exception zu werfen.
Nur müsstest du wiederrum das PClients.Remove(c) mit einem SyncLock versehen.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Probleme mit TCP 
Autor: Daddaaff
Datum: 22.06.11 20:28

Ok, wenn nun der ein Seite offline geht, muss muss ich die ausser PClients.Remove(c) die Verbindung noch weiter beenden? Eben mit c.stream.Close() oder c.Client.Client.Close() - also den Stream oder den TCPClient schließen?

Ich habe nun bemerkt, das anfangs die Datenübertregung funktioniert. Ich sehe das gesendet und Empfangen wird. Aber schon nach kurzer Zeit, wird zwar gesendet, aber nichtmehr empfangen. Jedoch tritt kein Exeption auf....
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Probleme mit TCP 
Autor: Preisser
Datum: 22.06.11 20:40

Hallo,

das weiß ich nicht genau, ich denke, dass es reichen müsste einfach den Stream oder das Socket zu schließen.

Wo genau wird nichts mehr empfangen, beim Server oder beim Client?
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Probleme mit TCP 
Autor: Daddaaff
Datum: 22.06.11 20:45

Soviel ich mitbekommen habe, beide! Meine einzige Idee wäre das die ListenToConnection() irgendwo hängen bleibt und somit den Stream natürlich nicht mehr liest! Jedoch konnt eich bisher nichts finden.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Probleme mit TCP 
Autor: Daddaaff
Datum: 22.06.11 20:57

Ich bekomme nun auf jeder Seite eine Exeption!

System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'System.Net.Sockets.NetworkStream'.
at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
at System.IO.StreamReader.ReadBuffer()
at System.IO.StreamReader.ReadLine()
at Server.Main1.ListenToConnection(Connection c)

und dort wo ich Debugge

System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host. ---> System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host
at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)
at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
--- End of inner exception stack trace ---
at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
at System.IO.StreamReader.ReadBuffer()
at System.IO.StreamReader.ReadLine()
at Server.Main1.ListenToConnection(Connection c) in E:\Projekte\P2P\Server\MainS.vb:line 1281

EDIT: Ich denke das der Fehler irgendwo in der ListenToConnection() liegt!
Sub ListenToConnection(ByVal c As Connection)
        Dim Info As String
        Dim Infos() As String
        Try
            c.streamw.WriteLine(PNodeID & "||" & PConnectable)
            c.streamw.Flush()
            Info = c.streamr.ReadLine
            If Info = Nothing Then
                'CloseClient(c)
                TXT("Eine Verbindung wurde vorzeitig beendet")
            Else
                Infos = Split(Info, "||")
                c.ClientID = Infos(0)
                SyncLock PClients
                    For Each cl As Connection In PClients
                        Dim cIP() As String
                        cIP = Split(cl.ClientID.ToString, ":")
                        If cIP(0) = Infos(0) Then
                            c.stream.Close()
                            Exit Sub
                        End If
                    Next
                    c.ClientIP = PClient.Client.RemoteEndPoint.ToString
                    PClients.Add(c) ' und fügen sie der liste der clients hinzu.
                End SyncLock
                TXT("Neuer Client: " & c.ClientID)
                Dim SplitMSG() As String
                Dim NewTTL As Integer
                Dim FullMSG As String
                While True
                    FullMSG = c.streamr.ReadLine
                    If FullMSG = Nothing Then
                        TXT("Die Verbindung zu " & c.ClientID & " wurde" & _
                          "beendet")
                        CloseClient(c)
                    Else
                        TXT(FullMSG)
                        SplitMSG = Split(FullMSG, PFullMSGSplit)
                         .
                         .
                         .
 
                        MSG(SplitMSG(3), c.ClientID, SplitMSG(4))
                        End If
                         .
                         .
                         .                        
                    End If
                End While
            End If
        Catch ex As Exception
            TXT(ex.ToString)
        End Try
    End Sub


Beitrag wurde zuletzt am 22.06.11 um 21:11:00 editiert.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Probleme mit TCP 
Autor: Preisser
Datum: 22.06.11 21:18

Hallo,

also du prüfst jetzt zwar, ob der Rückgabewert von ReadLine == Nothing ist, udn schließt dann auch den Stream; allerdings verlässt du ja dann die Schleife nicht und versuchst wieder, etwas zu lesen, was die ObjectDisposedException erklären dürfte. Nachdem du den Client getrennt hast, müsstest du auch die While-Schleife verlassen (Exit While).

Die andere Exception tritt normalerweise auf, wenn die Gegenseite die Verbindung hart geschlossen hat (z.B. wenn man den Prozess im Taskmanager beendet o.ä.). Dadurch weißt du dann auch, dass die Gegenseite die Verbindung getrennt hat.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Probleme mit TCP 
Autor: Daddaaff
Datum: 22.06.11 22:02

Habe den Übeltäter identifizieren können! c.ClientIP = PClient.Client.RemoteEndPoint.ToString muss natürlich c.ClientIP = c.Client.Client.RemoteEndPoint.ToString lauten.

Mal sehen ob nun alles funktioniert wie es soll!

Danke für eure unterstützung!
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Sie sind nicht angemeldet!
Um auf diesen Beitrag zu antworten oder neue Beiträge schreiben zu können, müssen Sie sich zunächst anmelden.

Einloggen  |  Neu registrieren

Funktionen:  Zum Thema  |  GesamtübersichtSuchen 

nach obenzurück
 
   

Copyright ©2000-2024 vb@rchiv Dieter Otter
Alle Rechte vorbehalten.
Microsoft, Windows und Visual Basic sind entweder eingetragene Marken oder Marken der Microsoft Corporation in den USA und/oder anderen Ländern. Weitere auf dieser Homepage aufgeführten Produkt- und Firmennamen können geschützte Marken ihrer jeweiligen Inhaber sein.

Diese Seiten wurden optimiert für eine Bildschirmauflösung von mind. 1280x1024 Pixel