UDP Discovery Tutorial – Part 2

In Part 1 of this article I showed how one might use UDP datagrams to discover a client or server on a connected system over an IPv4 network. In Part 2 I am going to add a subsequent TCP connection and briefly explain how it is done.


Now we add a TCP connection.

There is more than one way to approach adding a TCP connection to this example.  One of the simpler to understand approaches would be to use UDP to broadcast the listener’s IP back to the broadcaster after the listener received the broadcaster’s IP, and then create a TCP connection between the two specific IPs.

I am not using the above described method however. It seems to me to be a more usable approach to have the broadcaster asynchronously wait for an incoming TCP connection from any source, and once the connection is made authentication can be performed, but as with Part 1, I leave authentication and error handling up to the reader to implement.

Since we are using an asynchronous model for the TCP connection and communications, the pattern that all operations will follow is:

  1. Operation
  2. Callback
  3. Wait on Callback

We will also be using custom events to implement our waiting operations. These are created on lines 28 of the UDPBroacaster project and lines 27-29 of the UDPListener project.


Resolve the TCP address to an Endpoint

The first step we perform here is to resolve the TCP address that we are using to an endpoint object for the TCP client object to initialize itself with.

For the listener this is done using the IP received in the UDP datagram:

IPEndPoint remoteEP = new IPEndPoint(tcpAddress, tcpPort);

For the broadcaster this is done using it’s own host IP since we are accepting connections from any other address.

IPEndPoint localEndPoint = new IPEndPoint(localIP, tcpPort);


Connect to the Broadcaster

Once we have the endpoints we now attempt a connection to the UDPBroadcast application from the UDPListener application:

            // Connect to the remote endpoint
            client.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), client);
            connectDone.WaitOne();  // Without these waits other processing could continue
            listView.Items.Add("TCP Connection Established with UDPBroadcaster");


Asynchronously wait for connection

Now we listen for an incoming connection request from anyone within the UDPBroadcast application:

            // Bind the socket to the local endpoint and listen for incoming connections
            //  This logic will parrot back any message received

            // Start an asynchronous socket to listen for connections
                new AsyncCallback(AcceptCallback),

            // Wait until a connection is made before continuing
            listView.Items.Add("TCP Connection has been Established, and message received and returned");

The above listening logic for the UDPBroadcast application will asynchronously listen for a TCP connection, and once established, will wait for a message, read the message and return the same message back to the sender.  You can see all the logic for the above within the AcceptCallback() method which you can view by downloading the example projects for this tutorial.


Send some test data

Now that we have a connection established, we can send some data to make sure everything is connected up correctly.  We send a test message from within the UDPListener application:

            // Send test data to the remote device
            Send(client, "Hello, this is UDPListener!<EOF>");
            listView.Items.Add("Message sent to UDPBroadcast");

In a real application this initial message would likely be where you authenticate the connection between the two applications.


Wait for responce

Since the UDPBroadcast application is designed to parrot back any message it receives we can immediately wait for a response within the UDPListener application:

            // Receive the response from the remote device
            listView.Items.Add("Received the following responce from UDPBroadcast: "+response);


Close the Connection

Now that we have connected, sent, and received back data from the UDPBroadcast application we can close the TCP connection and release the socket:

            // Release the socket
            listView.Items.Add("Connection to UDPBroadcast application has been closed.");


Final Comments

The above is a very basic example, and as mentioned before error handling and proper authentication is necessary for using this in any real application.  Much of the described logic is encapsulated within the callback methods that can be viewed by downloading the completed example projects linked at the bottom of this article.

I hope this has been helpful to those that have come here to read it. And as always if you have suggestions for improvements to this article, or comments about anything that I’ve done wrong, please leave a comment below.





As always please refer to my references for further detail.  Much of the code has been compiled from the linked references. For the UDP references see Part 1 of this series.



Leave a Reply

Your email address will not be published. Required fields are marked *