UDP Chat im lokalen Netz

    • VB.NET

    Es gibt 19 Antworten in diesem Thema. Der letzte Beitrag () ist von filmee24.

      UDP Chat im lokalen Netz

      Mal ganz was einfaches fürs lokale Netz:

      Klasse:
      Spoiler anzeigen

      VB.NET-Quellcode

      1. Imports System.Threading
      2. Imports System.Net.Sockets
      3. Public Class UDPChatter
      4. Private _Port As Integer
      5. Private ars As New AutoResetEvent(False)
      6. Private stoplisten As Boolean
      7. Event GotMessage(ByVal m As String, ByVal remoteip As Net.IPEndPoint)
      8. Public Sub New(ByVal port As Integer)
      9. _Port = port
      10. End Sub
      11. Public Sub [Stop]()
      12. stoplisten = True
      13. ars.Set()
      14. End Sub
      15. Public Sub Listen()
      16. stoplisten = False
      17. Dim t As New Thread(AddressOf BackgroundListener)
      18. t.Start()
      19. End Sub
      20. Private Sub ReadCallback(ByVal ar As IAsyncResult)
      21. Dim u As UdpClient = DirectCast(ar.AsyncState, UdpClient)
      22. Dim rep As Net.IPEndPoint
      23. Dim b() As Byte = u.EndReceive(ar, rep)
      24. If b.Length > 0 Then
      25. Dim m As String = System.Text.Encoding.Unicode.GetString(b)
      26. Dim d As [Delegate] = GotMessageEvent
      27. For Each trg As [Delegate] In d.GetInvocationList
      28. If TypeOf trg.Target Is Control Then
      29. DirectCast(trg.Target, Control).Invoke(d, New Object() {m, rep})
      30. Else
      31. RaiseEvent GotMessage(m, rep)
      32. End If
      33. Next
      34. End If
      35. ars.Set()
      36. End Sub
      37. Private Sub BackgroundListener()
      38. Dim p As New Net.IPEndPoint(Net.IPAddress.Any, _Port)
      39. Dim u As New UdpClient()
      40. u.EnableBroadcast = True
      41. u.ExclusiveAddressUse = False
      42. u.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, True)
      43. u.Client.Bind(p)
      44. Do
      45. u.BeginReceive(AddressOf ReadCallback, u)
      46. ars.Reset()
      47. ars.WaitOne()
      48. Loop Until stoplisten
      49. End Sub
      50. Public Sub SendStr(ByVal s As String)
      51. Dim t As New Thread(AddressOf BackgroundSend)
      52. t.Start(s)
      53. End Sub
      54. Private Sub BackgroundSend(ByVal o As Object)
      55. Dim s As String = DirectCast(o, String)
      56. Dim p As New Net.IPEndPoint(Net.IPAddress.Broadcast, _Port)
      57. Dim u As New UdpClient()
      58. u.ExclusiveAddressUse = False
      59. u.EnableBroadcast = True
      60. u.DontFragment = True
      61. u.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, True)
      62. u.Client.Bind(New Net.IPEndPoint(Net.IPAddress.Any, _Port))
      63. Dim b() As Byte = System.Text.Encoding.Unicode.GetBytes(s)
      64. u.Send(b, b.Length, p)
      65. End Sub
      66. End Class


      Der Empfang ist nicht blockierend -> events
      Beachten, dass der Listener auf ALLEN verfügbaren IPs lauscht. Wenn mehr als eine NIC im Rechner ist (auch virtuell etc), kommt jede Nachricht u.U. mehrfach an. Also muss man entweder von .Any auf eine bestimmte umstellen, oder halt irgendwie die doppelten msgs filtern.

      Man kann das natürlich nicht nur zum Chatten, sondern auch für alle anderen Kommunitkationen verwenden.

      Bsp:
      Spoiler anzeigen

      VB.NET-Quellcode

      1. Public Class Form1
      2. Private WithEvents c As New UDPChatter(12345)
      3. Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
      4. c.Listen()
      5. End Sub
      6. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
      7. c.SendStr("Hallo")
      8. End Sub
      9. Private Sub c_GotMessage(ByVal m As String, ByVal rep As Net.IPEndPoint) Handles c.GotMessage
      10. ListBox1.Items.Add(m)
      11. End Sub
      12. End Class


      Da das ganze via Broadcast funzt, geht es natürlich nicht übers INet!
      Mahlzeit.

      Ich benutze deinen Codeschnipsel da um... naja um zu chatten. Von der Einfachheit bin ich absolut überzeugt, aber ich habe da dennoch ein kleines Problemchen.

      Immer, wenn eine Nachricht ankommt, kommt bei mir in der Zeile 40:

      DirectCast(trg.Target, Control).Invoke(d, New Object() {m, rep}) (In "ReadCallback")

      der Fehler "ArgumentOutOfRangeException" (Value mit dem Wert 0 wurde nicht behandelt)

      Ich bin, was VB2008 angeht, noch relativ unbewandert. Deshalb kann ich den Fehler irgendwie nicht nachvollziehen, vorallem, weil ich den Code auch nicht mehr angerührt habe. Irgend 'ne Idee?

      Frisky schrieb:

      Mahlzeit.
      DirectCast(trg.Target, Control).Invoke(d, New Object() {m, rep}) (In "ReadCallback")

      der Fehler "ArgumentOutOfRangeException" (Value mit dem Wert 0 wurde nicht behandelt)

      Irgend 'ne Idee?

      Mit F9 einen Breakpoint auf die Zeile setzen, Debug-Modus starten und dann dort mal schauen, wie die beteiligten Variablen aussehen.
      So, das von mir beschriebene Problem existiert nicht mehr. Warum weiß ich selbst nicht, aber es ist was neues aufgetreten.

      Wenn ein zweiter Rechner über das Programm anfängt zu broadcasten, passiert nichts mehr. Beide Programme senden und empfangen keine Nachrichten mehr.

      Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „Frisky“ ()

      Upps, tja das passiert, wenn man den Code net einfach so kopiert^^"
      Ich glaube ich sollte nicht immer den Code abschreiben und versuchen ihn zu verstehen...

      Naja danke mit dem Hinweis der Klasse

      #Edit

      UDPChatter(12345)

      Die Nummer ist die "Name" des Senders?
      Kann ich da nicht eine eindeutige Rechner-ID nehmen?

      Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „Biotechniker“ () aus folgendem Grund: weitere Frage

      Hi,danke für deine schnelle Antwort =)
      Wie meinst du Zeile? In dem der fehler ist?
      Hab ein Bild hochgeladen,wenn du möchtest kannst du dir das via. Teamviewer anschaun
      Bilder
      • VB Fehler.JPG

        141,02 kB, 1.279×954, 290 mal angesehen