[VB.Net 2005] TCP Kommunikation

forsterm

Erfahrenes Mitglied
Hallo,
also ich hab folgenden Code:
Code:
Imports System.Net
Imports System.Net.Sockets
Public Class Form1
    Dim conn As TcpClient
    Dim nstrm As System.IO.Stream
    Dim sr As System.IO.StreamReader
    Dim netBuff(1000 - 1) As Byte
    Dim enc As New System.Text.UTF8Encoding
    Dim dec As System.Text.Decoder    Dim listener As New TcpListener(Net.IPAddress.Any, 1738)
    Public Sub getData()
        If IsNothing(conn) Then
            listener.Start()
            conn = listener.AcceptTcpClient
            nstrm = conn.GetStream()
            dec = enc.GetDecoder
            nstrm.BeginRead(netBuff, 0, 1000, AddressOf cbr, Nothing)
        Else
            MsgBox("Server running")
        End If
    End Sub
    Private Delegate Sub setTextHandler(ByVal data As String)
    Public Sub cbr(ByVal ar As IAsyncResult)
        Dim cnt As Integer
        Dim data As String
        Dim chars() As Char
        Dim carryOn As Boolean = True
        Try
            cnt = conn.GetStream.EndRead(ar)
            Debug.WriteLine("Server Bytes read: " + cnt.ToString())
            If cnt = 0 Then
                carryOn = False
            Else
                ReDim chars(dec.GetCharCount(netBuff, 0, cnt) - 1)
                dec.GetChars(netBuff, 0, cnt, chars, 0)
                data = New String(chars, 0, chars.Length)
                Debug.WriteLine("Data received: " + data.Length.ToString() + " chars: " + data)

                txtResponse.Invoke(CType(AddressOf setText, setTextHandler), New String() {data})
                Debug.WriteLine("Restart read request")
                nstrm.BeginRead(netBuff, 0, 1000, AddressOf cbr, Nothing)
            End If
        Catch ex As System.Exception
            Debug.WriteLine("Error: " + ex.Message)
            carryOn = False
        End Try
        If Not carryOn Then
            nstrm.Close()
            conn.Close()
            listener.Stop()
            nstrm = Nothing
            conn = Nothing
        End If
    End Sub
    Private Sub setText(ByVal data As String)
        txtResponse.AppendText(data)
        Application.DoEvents()
    End Sub
    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        If IsNothing(conn) Then
            getData()
        End If
    End Sub
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Timer1.Start()
    End Sub
End Class
Also der Code macht folgendes und zwar wenn die Anwendung gestartet wird, wird ein TCP-Port
- in dem Fall TCP-Port 1738 - überwacht und alle Daten (Text) der an den Port
gesendet wird, wird in eine Textbox geschrieben. Das Problem bei meinem Code ist
jetzt, dass wenn ich die Anwendung start sie "einfriert" und das solange, bist ich Daten
(Text) an den besagten Port sende.

Hoffe hier weiß jemand woran das liegen könnt.

mfg
forsterm

Ps: Eventuell gibt es ja eine viel einfacher/kürzere Lösung. Ich will eigentlich nur
erreichen, dass alle Daten die an einen bestimmten Port gesendet werden in eine
Textbox geschrieben werden.
 
Jup. Ganz klar :)

Starte das Port-Listening in einem eigenen Thread und nicht über einen Timer. Du wirst vermutlich ein recht niedriges Intervall eingestellt haben und hast auch keine DoEvents() drinnen. Dadurch wird einerfach dein GUI-Thread blockiert.

Also, einen eigenen Thread starten, darin den TcpListener instanzieren und einstellen und die empfangenen Daten via Invoke an deine TextBox weiterreichen. Dann wird nichts mehr blockiert.
 
Starte das Port-Listening in einem eigenen Thread und nicht über einen Timer.
Hallo,
also ich muss gestehen, der Code ist nicht von mir . :-( Leider weiß ich erlich gesagt nicht wie du das meinst. :-(
Hast du da vielleicht irgendwo eine Quelle wo ich das nachlesen kann bzw. generell ein Quelle wo ich vb.net so richtig lernen kann?

mfg
forsterm
 
Hallo,
ok, also da ich mit dem anderen Code irgendwie nicht zu recht gekommen bin, hab ich mir jetzt folgendes selbst zusammen geschrieben.
Code:
Imports System.IO
Imports System.Net
Imports System.Net.Sockets
Public Class Form1
    Dim bytes(1000 - 1) As Byte
    Dim client As TcpClient
    Dim dec As System.Text.Decoder
    Dim listener As New TcpListener(Net.IPAddress.Any, 23)
    Dim reader As StreamReader
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        listener.Start()
        Timer1.Start()
    End Sub
    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        If listener.Pending = True Then
            client = listener.AcceptTcpClient()
            reader = New StreamReader(client.GetStream())
            txtResponse.AppendText(reader.Read)
        End If
    End Sub
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        If listener.Pending = True Then
            client = listener.AcceptTcpClient()
        End If
    End Sub
End Class
Jedoch wird irgendwie nur das erste Zeichen ausgegeben und ich weiß nicht woran das liegen könnte. :rolleyes:

Vielleicht kann mir da ja jemand von euch helfen. :)

mfg
forsterm
 
Schau mal in diesen [thread=266297][VB .Net 2005] Anzahl der Verbindungen begrenzen bei TcpClient und/oder Socket - Thread[/thread] und klick Dich mal da durch. Vielleicht findest etwas, was dir weiter hilft. Ich hab im Moment leider nicht die Zeit, deinen Code zu analysieren.
 
Schau mal in diesen [thread=266297][VB .Net 2005] Anzahl der Verbindungen begrenzen bei TcpClient und/oder Socket - Thread[/thread] und klick Dich mal da durch. Vielleicht findest etwas, was dir weiter hilft. Ich hab im Moment leider nicht die Zeit, deinen Code zu analysieren.
Hallo,
leider hilft mir der Thread nicht wirklich weiter. :(
Vielleicht kann mir ja jemand anders weiterhelfen? :rolleyes: ;)

mfg
forsterm
 
ich habe im Moment das gleiche Problem. Ich werde morgen mal versuchen das Ganze über Threads zu realisieren. Ich habe ja vorher mit VB 6.0 gearbeitet, und da ging das Ganze mit dem Winsock Seuerelement ein ganzes Stück einfacher. Hier http://www.codeproject.com/useritems/winsock2005.asp
gibts ein Projekt, bei dem das "alte" Winsock Steuerelement für .NET angepasst wurde. Allerdings will ich die Funktion lieber selber implementieren, obwohl es wohl damit wesentlich einfacher geht.

Allerdings würde mich wirklich brennend interessieren, ob es da keine andere Lösung gibt als Threads. Wär toll wenn sich hier mal ein Profi die Zeit nehmen könnte, ein absolut simples TCP Chat Programm zu schreiben. Also ein Server und ein Client, mit Textboxen für Empfand und Versand. In VB 6.0 ging das mit dem Winsock Steuerelement ratz fatz. Da gabs halt Ereignisse für tcp_connectionrequest und tcp_dataarrival. Ich steh hier wirklich auf dem Schlauch ( und es gibt auch Viele Andere, wie ich beim googeln bemerkt habe).
 
Zuletzt bearbeitet:
Wenn man sich mal intensiv durch die Links durchklicken würde, die ich poste, würde man auch herraus finden, dass man das ganze auch Asynchron implementieren kann.
Dann benötigt man lediglich einen Thread, der in einer Schleife auf neue Verbindungsanforderungen wartet. Alle Anfragen der Clients werden dann wie Ereignisse behandelt, und automatisch in separaten Threads ausgeführt.

Bevor man sich da herran macht, sollte man sich die Beispiele in der MSDN anschauen um sich einen Überblick zu verschaffen. Wenn es immer noch Probleme gibt, kann ich mal ein Beispiel in C# machen. Vielleicht sogar ein Tutorial, kommt aber auf meine verfügbare Zeit und eure Votings dafür an...
 
joa das Ganze hat geklappt mit asynchronen Methodenaufrufen. Sowas kannte ich halt vorher nicht ;) Wie kann man denn nun den Verbindungsstatus prüfen ? Ich finde da kein Eigenschaft beim TCPClient ausser .connected. Aber da wird nur der Verbindungsstatus der letzten E/A Aktion angezeigt.. ich will aber permanent den aktuellen haben
 
Dann musst es in deinem Protokoll implementieren und zyklisch anfragen ob der Client verfügbar ist. Wenn er nicht antwortet, hast den Beweis. Und wenn Du Dir ein Property dafür implementiert hast, führst die Abfrage während des Zugriffs auf das Property explizit aus. Hab ich bereits so in der Art schon mal gepostet. Findest das auch in den Links (durchklicken :))...
 
Zuletzt bearbeitet:
Zurück