How to find and register multiple UDP broadcasters in real time on the same LAN in VB.NET?

51 Views Asked by At

I am building an app that requires a P2P-style model to operate. I am using UDP broadcasting for nodes to find other online nodes at that time, by sending an ack message in a specific format to all devices on a LAN on a specific port used by my app. However, I am encountering an issue picking up any devices other than my own device/the same node, i.e.the only broadcasters my nodes pick up are themselves, and no others. I have looked at many online resources, but found nothing that helps in my case.

Here is my code in simplified form :

Imports System.Net
Imports System.Net.Sockets
Imports System.Text.Encoding
Imports System.Threading

Public Sub Initialise()
    Public Const ServerPort As Integer = 24000 '24000 will be the port for server comms between peers
    Public Const ClientPort As Integer = 36000 '36000 will be the port for client comms between peers

    Public DeviceIP As IPAddress = GetOwnIP()'returns the local IP of device

    Private UDPAckClient As UdpClient = New UdpClient(ClientPort) With {.EnableBroadcast = True} 'broadcasting client - all devices broadcast from 36000 to 24000
    Private UDPAckEndpoint As IPEndPoint = New IPEndPoint(IPAddress.Broadcast, ServerPort) 'endpoint for broadcasters - to all LAN IP's on port 24000

    Private UDPAckListenerClient As UdpClient = New UdpClient(ServerPort)
    Private UDPAckListenerEndpoint As IPEndPoint = New IPEndPoint(IPAddress.Any, ServerPort)

    Private AckBroadcastThread As Thread = New Thread(AddressOf AckBroadcaster) With {.IsBackground = True}
    Private AckListenerThread As Thread = New Thread(AddressOf AckListener) With {.IsBackground = True}

    Try
        AckBroadcastThread.Start()
        AckListenerThread.Start()
    Catch ex As Exception
        Console.WriteLine("Error initialising threads: " + ex.Message + ": " + TimeString)
    End Try
End Sub

Private Sub AckListener() 'udp listener server for receiving broadcasts
    Console.WriteLine("Listening to port 24000.")
    Try
        While AppRunning
            Dim ReceivedBytes As Byte()
            Try
                ReceivedBytes = UDPAckListenerClient.Receive(UDPAckListenerEndpoint)
            Catch ex As Exception
                ReceivedBytes = {99}
            End Try
            Dim Msg As String = ASCII.GetString(ReceivedBytes)

            If Msg.StartsWith(AppIDMessage) And UDPAckListenerEndpoint.Address IsNot GetOwnIP() Then 'AppIDMessage is a constant for my app, e.g. "MyApp..."
                Console.WriteLine("New broadcaster found." + UDPAckListenerEndpoint.Address.ToString + ":" + UDPAckListenerEndpoint.Port.ToString + ", " + TimeString)
            End If
        End While
    Catch ex As Exception
        Console.WriteLine("Error while listening to UDP: " + ex.Message + " at " + TimeString)
    End Try
End Sub

Private Sub AckBroadcaster() 'broadcaster thread sends (1000/n) datagrams per second, where n is the thread sleep value

    Console.WriteLine("Broadcasting to port 24000.")
    While AppRunning
        Try
            Dim BCMsg() As Byte = ASCII.GetBytes(BroadcastMessage) 'BroadcastMessage is a string consisting of specific parts for other devices to recognise on the network
            UDPAckClient.Send(BCMsg, BCMsg.Length, UDPAckEndpoint)
            Thread.Sleep(17)
        Catch ex As Exception
            Console.WriteLine("Error while sending datagram: " + ex.Message + ": " + TimeString)
        End Try
    End While
End Sub

With two devices running correctly, this is the output of each device:

Device 1 has IP 192.168.1.104 Device 2 has IP 192.168.1.118

Device 1 only prints "New broadcaster found: 192.168.1.104:36000 ..." Device 2 similarly prints the same but with only its own IP.

To note, I have a list that is updated every time a new broadcaster is found, and this is checked in the AckListener() While loop, to avoid hundreds of console outputs of the same thing. However, even without it, the only IP's coming up are my own. When I filter out my own IP in the If statement, no other broadcasts come through, even with 2 other devices running the same code.

Could you suggest a way for me to fix the code so that all broadcasters are picked up, either by fixing my existing code, or suggesting a different solution altogether.

0

There are 0 best solutions below