Click here to Skip to main content
15,879,535 members
Articles / Desktop Programming / Windows Forms
Article

TinyUDP - Simple UDP Client/Server Components for .NET

Rate me:
Please Sign up or sign in to vote.
4.42/5 (21 votes)
7 Jun 20054 min read 309.3K   11.6K   62   55
Simple UDP client/server components for .NET 1.1.

Image 1

Introduction

This article was written in the course of implementing a simple method for a Windows service to communicate status information to a front-end administration application. This article was written using the excellent article UDP send and receive using threads in VB.NET by Kumudu Gunasekara for inspiration and 'spiritual guidance', as well as some nifty ideas. Kumudu's article is definitely worth reading.

Background

I decided to implement a simple UDP client/server system for simple communication between my Windows service and the administration program for a variety of reasons:

  1. UDP is lightweight and fast compared to other protocols, such as TCP. This was important to me, as my Windows service needed to maintain high performance.
  2. UDP is connectionless, which means that it can fire off a message and immediately free server-side network resources. Incidentally, this also makes UDP one of the easiest protocols to write a client/server application for.
  3. UDP preserves message boundaries transmitting entire messages at once.

Some of the drawbacks of UDP are:

  1. UDP does not guarantee delivery or provide for acknowledgment of receipt of messages. In this instance, that was perfectly acceptable since I was simply passing the status data from the Windows service to the UI layer.
  2. UDP has practical limits on how much data can be sent in a single message - usually limited to 1500 Bytes per message or less. Again, this limitation worked well given my scenario - I would normally not be passing more than 100 bytes per message.

Using the code

The code is pretty straightforward and well documented. There are two components: Tiny.UDP.TinyServer and Tiny.UDP.TinyClient. They are .NET 1.1 components, so they can be added to your Toolbox and dropped right in your Windows Forms; or you can reference them (as I did in the sample applications) by creating objects in the code. The code to create a server looks like this:

VB
' Initialize a TinyServer Object
Dim server As New TinyServer

' Set it for UDP and assign the destination end point
server.Protocol = ProtocolType.Udp
server.ClientAddress = IPAddress.Parse("127.0.0.1")
server.ClientPort = 8088

' Set the Encoding Type and Send the Message
server.Encode = EncodingType.ASCII

All we're doing here is:

  1. Creating the TinyServer object.
  2. Setting the communications protocol (currently only UDP is supported), client IP address and client port.
  3. And finally, setting the message encoding type (ASCII, UNICODE, UTF7, UTF8 and all others are supported).

Next we set up the TinyClient:

VB
' Define a TinyClient object
Dim WithEvents client As TinyClient

' Create a client object
client = New TinyClient

' Set the inbound client port
client.ClientPort = 8088

' Set the encoding type and protocol
client.Encode = EncodingType.ASCII
client.Protocol = ProtocolType.Udp

Again, it's a simple matter to set up a client:

  1. Define and create a new TinyClient object. Notice it is declared WithEvents.
  2. Set the inbound client port number.
  3. Set the encoding type and protocol to match the TinyServer that we created.

That's a simple UDP client and server with just 10 lines of code! (Not counting comments of course.) Finally, we start the client running with the Start() method:

VB
client.Start()

and send messages from the server with the SendMessage() method:

VB
server.SendMessage ("This is a UDP Message sent by TinyServer.")

The TinyClient object was declared WithEvents because it implements two events: BeforeReceive and AfterReceive. BeforeReceive is fired immediately before receiving data off the wire. AfterReceive is fired immediately after the client finishes receiving data. You can set up your own subroutines to handle these events as you see fit. Other events may be added later; but for now I decided those two were the most important to get implemented.

How does it work?

If you look into the code, you will see that the TinyServer simply creates a System.Net.Sockets.UdpClient, opens a connection, and fires off your message when you call the SendMessage() method. Very simple. The client is where the fun begins.

On the client side, the Start() method actually fires off a worker thread that in turn starts its own System.Net.Sockets.UdpClient and waits for data. We set it off on a separate worker thread because the Receive() method blocks the current thread until it completes - and we don't need it locking up our UI. Once a message is received by the worker thread, the thread exits immediately, so we start a new worker thread to continue waiting for the next message.

Because these events are fired from the worker thread, you'll notice in the sample program that I check Me.InvokeRequired on the client form before I update it. This is necessary because of the nature of multi-threaded apps; never update the UI from a worker thread, always check InvokeRequired and use Invoke if it is True.

Finally, when we finish, fire the client.Stop() method to stop the worker thread and cleanly dispose off the UDPClient.

Points of interest

As mentioned previously, this works best on a local machine or on locally networked computers; for instance, when communicating non-critical information between layers of a locally installed application. It also has the potential for chat applications, which I'm sure has been done to death by now :) My main goal in designing this was to create a reusable, lightweight set of components that could be used to allow Windows services to easily communicate with the front-end client applications without jumping through hoops.

Enjoy!

History

  • June 8th, 2005 - version 0.8.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
United States United States
Database Admin (MCDBA) and Programmer with 15+ years' experience in data warehousing, application design and development, and systems integration.

Comments and Discussions

 
Questionhelp Pin
Gigi Carlino26-Oct-06 6:14
Gigi Carlino26-Oct-06 6:14 
GeneralHelp ... Create new Form from worker thread Pin
RG_SA19-Sep-06 23:26
RG_SA19-Sep-06 23:26 
GeneralMemory Usage in Task Manager Pin
brembot2-Aug-06 5:41
brembot2-Aug-06 5:41 
GeneralHELP I NEED A GOOD UDP SOURCE Pin
Fulmine23-Jan-06 4:50
Fulmine23-Jan-06 4:50 
GeneralProgram not closing; tried lots of things... Pin
Daniël_T3-Jan-06 12:29
Daniël_T3-Jan-06 12:29 
GeneralRe: Program not closing; tried lots of things... Pin
NairbNilpop1-Feb-06 16:30
NairbNilpop1-Feb-06 16:30 
GeneralRe: Program not closing; tried lots of things... Pin
Ari Vesteinsson19-Sep-06 5:32
Ari Vesteinsson19-Sep-06 5:32 
GeneralMultithreading start/stop question Pin
davidm991-Dec-05 10:09
davidm991-Dec-05 10:09 
I'm not too familiar with threads and everything, but in my program I do a lot of client.stop and client.starts... (Possibly a couple thousand times in 24 hours!) (this is because I use the same server.sourceport as my port the client is listening on) I notice when the program first opens, and you first start the server, the cpu usage stays relatively small, normally @ 0%. BUT, whenever I stop the server, then start it again, CPU usage jumps up to 99% and stays relatively there.

Do you know any reason this could be? I read something about suspending threads and then resuming them, would this work instead of stopping and starting?
QuestionInvoke Pin
Lost-Ha[n]f-PHP24-Nov-05 1:31
Lost-Ha[n]f-PHP24-Nov-05 1:31 
AnswerRe: Invoke Pin
tupacs0128-Nov-05 3:36
tupacs0128-Nov-05 3:36 
GeneralConfusing naming convention Pin
meraydin15-Nov-05 10:25
meraydin15-Nov-05 10:25 
GeneralRe: Confusing naming convention Pin
tupacs0128-Nov-05 3:40
tupacs0128-Nov-05 3:40 
GeneralRe: Fix for naming convention and exit bug Pin
Danilo Corallo20-Feb-07 21:45
Danilo Corallo20-Feb-07 21:45 
GeneralProgram Continues To Run After Close Pin
Duckdoo14-Nov-05 3:57
Duckdoo14-Nov-05 3:57 
GeneralRe: Program Continues To Run After Close Pin
davidm9915-Nov-05 9:57
davidm9915-Nov-05 9:57 
GeneralRe: Program Continues To Run After Close Pin
tupacs0128-Nov-05 3:58
tupacs0128-Nov-05 3:58 
GeneralSetting Origin Port Pin
davidm998-Nov-05 11:04
davidm998-Nov-05 11:04 
GeneralRe: Setting Origin Port Pin
davidm9915-Nov-05 10:04
davidm9915-Nov-05 10:04 
GeneralRe: Setting Origin Port Pin
davidm9915-Nov-05 10:05
davidm9915-Nov-05 10:05 
GeneralRe: Setting Origin Port Pin
tupacs0128-Nov-05 3:43
tupacs0128-Nov-05 3:43 
GeneralIP address of packet sender Pin
davidm995-Nov-05 6:21
davidm995-Nov-05 6:21 
GeneralRe: IP address of packet sender Pin
davidm995-Nov-05 6:26
davidm995-Nov-05 6:26 
QuestionMulticast Receiver... Pin
Member 1296784128-Sep-05 1:56
Member 1296784128-Sep-05 1:56 
AnswerRe: Multicast Receiver... Pin
tupacs0128-Nov-05 3:56
tupacs0128-Nov-05 3:56 
Generalrunning an windows application as a clent server applicaion Pin
behzad608125-Sep-05 20:47
behzad608125-Sep-05 20:47 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.