Announcement

Collapse
No announcement yet.

Thread wird dreimal ausgegeben

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Thread wird dreimal ausgegeben

    Hallo,

    ich hoffe mir kann jemand weiter helfen. Ich hab untenstehenden Code im Internet gefunden und möchte diesen gerne weiter ausbauen aber bevor ich das machen kann muss daran etwas gebastelt werden. Das Problem was ich habe ist das die Ausgabe dreimal wieder gegeben wird. Wenn man sich den Code kopiert und 2 Textfelde und eine Button dazu macht und es dann testet passiert folgendes. Gibt man in dem Textfeld txtMensaje etwas ein, drückt dann auf den Button cmdEnviar taucht im zweiten Textfeld txtDatosRecibidos die Eingabe dreimal auf. Was müsste am Code verändert werden damit die Aufgabe aber nur einmal zutrifft. Kann mir da bitte jemand weiter helfen.

    Code:
    Imports System.Net
    Imports System.Net.Sockets
    Imports System.Text
    Imports System.Threading
    
    Public Class frmMain
        Dim ElSocket As New Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)
        Dim HiloRecibir As Thread
        Dim Saliendo As Boolean = False
        Dim DireccIP As String, ContenidoMensaje As String
        Private Sub txtMensaje_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtMensaje.TextChanged
            cmdEnviar.Enabled = (txtMensaje.TextLength > 0)
        End Sub
        Private Sub cmdEnviar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdEnviar.Click
            Dim DirecciónDestino As New IPEndPoint(IPAddress.Broadcast, 20145)
            Dim DatosBytes As Byte() = Encoding.Default.GetBytes(txtMensaje.Text)
            ElSocket.SendTo(DatosBytes, DatosBytes.Length, SocketFlags.None, DirecciónDestino)
            txtMensaje.Clear()
            txtMensaje.Focus()
        End Sub
        Private Sub frmMain_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
            Saliendo = True
            ElSocket.Close()
            HiloRecibir.Abort()
        End Sub
        Private Sub frmMain_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
            ElSocket.Bind(New IPEndPoint(IPAddress.Any, 20145))
            ElSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, True)
            HiloRecibir = New Thread(AddressOf RecibirDatos)
            HiloRecibir.Start()
        End Sub
        Private Sub RecibirDatos()
            Do
                Dim LaIPRemota As New IPEndPoint(IPAddress.Any, 0)
                Dim IPRecibida As EndPoint = CType(LaIPRemota, EndPoint)
                Dim RecibirBytes(255) As Byte
                Dim Datos As String = ""
                Try
                    ElSocket.ReceiveFrom(RecibirBytes, RecibirBytes.Length, SocketFlags.None, IPRecibida)
                    Datos = Encoding.Default.GetString(RecibirBytes)
                Catch ex As SocketException
                    If ex.ErrorCode = 10040 Then
                        Datos &= "[truncado]"
                    Else
                        MsgBox("Error '" & ex.ErrorCode.ToString & "' " & ex.Message, MsgBoxStyle.Critical, "Error al recibir datos")
                    End If
                End Try
                LaIPRemota = CType(IPRecibida, IPEndPoint)
                DireccIP = LaIPRemota.Address.ToString
                ContenidoMensaje = Datos.ToString
                txtDatosRecibidos.Invoke(New EventHandler(AddressOf ActualizarTextoMensaje))
            Loop Until Saliendo
        End Sub
        Private Sub txtDatosRecibidos_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles txtDatosRecibidos.TextChanged
            txtDatosRecibidos.SelectionStart = txtDatosRecibidos.TextLength
            txtDatosRecibidos.ScrollToCaret()
        End Sub
        Protected Sub ActualizarTextoMensaje(ByVal sender As Object, ByVal e As System.EventArgs)
            If txtDatosRecibidos.TextLength = 0 Then
                txtDatosRecibidos.Text = DireccIP & ">" & ContenidoMensaje
            Else
                txtDatosRecibidos.Text &= vbCrLf & DireccIP & ">" & ContenidoMensaje
            End If
        End Sub
    End Class
    Pösö: Die Namensvergabe der Textfelden stamme nicht aus meiner Feder. Wie schon gesagt, ein Fund aus dem Internet

  • #2
    Hi,

    wollte mich nur kurz melden und bekannt geben das mir jemand bei meinem Problem geholfen hat. Anbei möchte ich den Code hier rein posten falls jemand anderes mal auf diese Problem stoßen könnte.

    Code:
    Imports System.Net
    Imports System.Net.Sockets
    Imports Encoding = System.Text.Encoding
    
    Public Class Form1
       'Objekt, um SyncLock zu erhalten
       Private _objSync As New Object
    
       Private _sockSend As New Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)
       Private _sockRead As New Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)
       Private _epReceive As EndPoint
    
       Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
          'Emfangssocket an Endpoint binden und Empfang starten
          'Wenn die IP des Endpoints eine konkrete IP ist, kommt die
          'Message nur einmal. Wenn die IP 0.0.0.0 = IPAddress.Any
          'kommt die Message so oft rein, wie IP-Adressen da sind,
          'wenn gleichzeitig der Sender einen Broadcast macht
          Dim ipBind As IPAddress = IPAddress.Any
          'Dim ipBind As IPAddress = IPAddress.Parse("10.0.0.1")
          Dim epBind As EndPoint = New IPEndPoint(ipBind, 23232)
          _sockRead.Bind(epBind)
    
          'Festlegen, von welcher Adresse wir empfangen wollen
          Dim ipRec As IPAddress = IPAddress.Any
          _epReceive = New IPEndPoint(ipBind, 23232)
          Dim buff(8192 - 1) As Byte
          'Asynchronen Empfang starten
          _sockRead.BeginReceiveFrom(buff, 0, buff.Length, SocketFlags.None, _
           _epReceive, AddressOf ReceiveCallback, buff)
       End Sub
    
       Private Sub Form1_FormClosed(ByVal sender As Object, ByVal e As FormClosedEventArgs) _
        Handles Me.FormClosed
          'Zugriff auf Read-Socket für andere Threads sperren
          'Verhindert SockRead.EndReceiveForm und erneutes SockReadBeginReceiveFrom 
          'in ReceiveCallback
          SyncLock _objSync
             _sockRead.Shutdown(SocketShutdown.Receive)
             _sockRead.Close()
             _sockRead = Nothing
          End SyncLock
       End Sub
    
       'Emfpang
       Private Sub ReceiveCallback(ByVal ar As IAsyncResult)
          Try
             Dim buff As Byte() = CType(ar.AsyncState, Byte())
             'Dieser Enpoint kann eine beliebige Addresse sein,
             'da wir für EndReceive nur eine Instanz von EndPoint brauchen
             Dim ep As EndPoint = New Net.IPEndPoint(IPAddress.None, 0)
    
             Dim intRead As Integer
             'Zugriff auf Read-Socket für andere Threads sperren
             'Verhindert dass in Form_Closed der Socket geschlossen
             'wird während wir hier den Lesevorgang abschließen
             SyncLock _objSync
                If _sockRead Is Nothing Then Return
                intRead = _sockRead.EndReceiveFrom(ar, ep)
             End SyncLock
             Dim received As String = ep.ToString & "> "
             If intRead > 0 Then
                received &= Encoding.Default.GetString(buff, 0, intRead)
    
                'Ergebnis an Hauptthread übergeben
                Dim d As New UpdateTextboxDelegate(AddressOf UpdateTextbox)
                Me.BeginInvoke(d, received)
                buff = New Byte(buff.Length - 1) {}
    
                'Zugriff auf Read-Socket für andere Threads sperren
                'Verhindert dass in Form_Closed der Socket geschlossen
                'wird, während wir erneut zu Lesen anfangen
                SyncLock _objSync
                   If _sockRead Is Nothing Then Return
                   _sockRead.BeginReceiveFrom(buff, 0, buff.Length, SocketFlags.None, _
                    _epReceive, AddressOf ReceiveCallback, buff)
                End SyncLock
             End If
          Catch exSock As SocketException
             MsgBox(exSock.Message & " " & exSock.ErrorCode)
          Catch ex As Exception
             MsgBox(ex.Message)
          End Try
       End Sub
    
       'Delegat, um den empfangenen Text an Hauptthread zu übergeben
       Private Delegate Sub UpdateTextboxDelegate(ByVal received As String)
    
       Private Sub UpdateTextbox(ByVal recieved As String)
          'In der Zwischenzeit kann die Form geschlossen worden sein
          'Deswegen updaten wir unsere Textbox nur, wenn noch alles "da" ist
          If Me.IsDisposed OrElse txtReceive.IsDisposed Then
             Return
          End If
    
          txtReceive.Text &= recieved & vbCrLf
          txtReceive.SelectionStart = txtReceive.Text.Length
       End Sub
    
       Private Sub cmdSend_Click(ByVal sender As Object, ByVal e As System.EventArgs) _
        Handles cmdSend.Click
          If txtSend.Text.Length = 0 Then Return
          Dim bytes As Byte() = Encoding.Default.GetBytes(txtSend.Text)
    
          'SendeSocket auf Broadcast festlegen
          _sockSend.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, True)
          _sockSend.SendTo(bytes, New IPEndPoint(IPAddress.Broadcast, 23232))
       End Sub
    
    End Class

    Comment

    Working...
    X