Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Simple C# UDP server/client in 56 lines
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace UDP
{
public class UDPSocket
{
private Socket _socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
private const int bufSize = 8 * 1024;
private State state = new State();
private EndPoint epFrom = new IPEndPoint(IPAddress.Any, 0);
private AsyncCallback recv = null;
public class State
{
public byte[] buffer = new byte[bufSize];
}
public void Server(string address, int port)
{
_socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.ReuseAddress, true);
_socket.Bind(new IPEndPoint(IPAddress.Parse(address), port));
Receive();
}
public void Client(string address, int port)
{
_socket.Connect(IPAddress.Parse(address), port);
Receive();
}
public void Send(string text)
{
byte[] data = Encoding.ASCII.GetBytes(text);
_socket.BeginSend(data, 0, data.Length, SocketFlags.None, (ar) =>
{
State so = (State)ar.AsyncState;
int bytes = _socket.EndSend(ar);
Console.WriteLine("SEND: {0}, {1}", bytes, text);
}, state);
}
private void Receive()
{
_socket.BeginReceiveFrom(state.buffer, 0, bufSize, SocketFlags.None, ref epFrom, recv = (ar) =>
{
State so = (State)ar.AsyncState;
int bytes = _socket.EndReceiveFrom(ar, ref epFrom);
_socket.BeginReceiveFrom(so.buffer, 0, bufSize, SocketFlags.None, ref epFrom, recv, so);
Console.WriteLine("RECV: {0}: {1}, {2}", epFrom.ToString(), bytes, Encoding.ASCII.GetString(so.buffer, 0, bytes));
}, state);
}
}
}
using System;
namespace UDP
{
class Program
{
static void Main(string[] args)
{
UDPSocket s = new UDPSocket();
s.Server("127.0.0.1", 27000);
UDPSocket c = new UDPSocket();
c.Client("127.0.0.1", 27000);
c.Send("TEST!");
Console.ReadKey();
}
}
}
@MakarGlavanar

This comment has been minimized.

Copy link

@MakarGlavanar MakarGlavanar commented Oct 17, 2018

You helped me so much! Thank you!

@nameofSEOKWONHONG

This comment has been minimized.

Copy link

@nameofSEOKWONHONG nameofSEOKWONHONG commented Oct 28, 2018

Thank you for your code.

@TTAliA

This comment has been minimized.

Copy link

@TTAliA TTAliA commented Nov 28, 2018

This is really good. So much better than any of the online snippets on UdpClient. Thank you!

@aangrisani

This comment has been minimized.

Copy link

@aangrisani aangrisani commented Jan 24, 2019

Sorry,
I am working on a UDP snmp trap server listner.
I would like to know the mean of this:

_socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.ReuseAddress, true);

I use a specific Ip Address, configured by application configuration file.
It is really important?
thanks

@simonemarra

This comment has been minimized.

Copy link

@simonemarra simonemarra commented May 17, 2019

thank you!

@AdityaSher

This comment has been minimized.

Copy link

@AdityaSher AdityaSher commented Jun 27, 2019

Thank you I was not able to understand most of the other codes online, your code is very simplified, I am grateful that you have had posted this.

@FoolishFrost

This comment has been minimized.

Copy link

@FoolishFrost FoolishFrost commented Jul 6, 2019

I don't mean to dismiss your work, but you might want to be advised that your code above does not deal with constant streams of data.

If data is being sent in bursts, then you get back corrupted data on the receiving system. It will respond with data from send 8 out of 10 in a burst, twice, and be missing item 9 of the burst of sends. (or other combinations)

@Blacklock

This comment has been minimized.

Copy link

@Blacklock Blacklock commented Jul 16, 2019

@FoolishFrost How would you suggest the code be improved?

@FoolishFrost

This comment has been minimized.

Copy link

@FoolishFrost FoolishFrost commented Jul 16, 2019

At this point, I have to say it was due to the ordering of the _socket.BeginReceiveFrom on line 51. Due to the ordering, it was missed that it needed to be the last thing in the series of lines.

Due to the order mismatch, I was getting false responses in the console out of order. If I placed the console before that line, the issue went away.

Easy to fix, once I was able to backtrack it, but it was odd how that simple ordering change was confusing the console output. New people looking at the code could easily add new lines after line 51, leading order data order issues, what looks like data corruption, and the like.

So, it just comes down to making sure the core loop actually contained everything inside of it.

Thanks for asking, I forgot about this thread.

@darkguy2008

This comment has been minimized.

Copy link
Owner Author

@darkguy2008 darkguy2008 commented Jul 16, 2019

Well this is interesting, I'm glad I've helped a lot of people with this gist, honestly I never thought it'd get so much attention haha, it was more like a way to show others how to make a simple client/server and also as a guide for me in case I forgot how to, for future projects haha.

UDP actually works in a way that packets won't come in order, always. That's why it's UDP. With TCP you have that guarantee, which is why it's a bit slower than UDP too. However, if there's indeed a fix for the code, let me know, if you can post a fixed version I can update the first gist so we all can benefit.

Thanks!

@louis-e

This comment has been minimized.

Copy link

@louis-e louis-e commented Jul 22, 2019

Can anyone help me how to close this server correctly, so I can start him again? I tried s1._socket.Dispose();, s1._socket.Disconnect(true);, s1._socket.Close(); and always when I want to start the server again, it drops runtime errors.

I am grateful for any kind of help,
Louis

@louis-e

This comment has been minimized.

Copy link

@louis-e louis-e commented Jul 23, 2019

Okay, I found the bug and I fixed it in a fork of your Gist.
https://gist.github.com/louis-e/888d5031190408775ad130dde353e0fd

@ishankapur

This comment has been minimized.

Copy link

@ishankapur ishankapur commented Sep 11, 2019

thank you man! you are a legend...

@flameleo11

This comment has been minimized.

Copy link

@flameleo11 flameleo11 commented Sep 26, 2019

good job

@MaxiCamilo

This comment has been minimized.

Copy link

@MaxiCamilo MaxiCamilo commented Jan 29, 2020

Perfect, thank you!

@renanliberato

This comment has been minimized.

Copy link

@renanliberato renanliberato commented Mar 1, 2020

Awesome!! Thank you!!

@DimaRichMain

This comment has been minimized.

Copy link

@DimaRichMain DimaRichMain commented Mar 29, 2020

Not bad, smart concept

@JoshuaDoes

This comment has been minimized.

Copy link

@JoshuaDoes JoshuaDoes commented Sep 21, 2020

I'm sorry if this is a really dumb question, I'm relatively new to writing C# from scratch (I normally just edit preexisting code to fix issues and patch functionality), but would my receive data handler have to go inside of this class's Receive method? Or is there a way for me to have Receive return a new packet if it finds one or return an empty byte array if it doesn't? Due to my functional programming background I'd rather do the latter

@SchneiderJonathan

This comment has been minimized.

Copy link

@SchneiderJonathan SchneiderJonathan commented Nov 10, 2020

@JoshuaDoes : If you want to acsess the received data from outside i would suggest using an event callback (thats what i did, @op thanks for the code btw). Therefore you need to define the delegate public delegate void UdpOnReceived(byte[] data, int bytesRead); should add the public field public event UdpOnReceived OnReceived; to the UDPSocket-Class and add OnReceived?.Invoke(state.buffer, bytes); to the Receive function.
Now you would be able to attach a listener from outside to the Class like var socket = new UDPSocket(); //...blablabla... socket.OnReceived += MyReactionFunction;. Then you could play with your data inside of those MyReactionFunctions.

@ReedTrev

This comment has been minimized.

Copy link

@ReedTrev ReedTrev commented Nov 25, 2020

@SchneiderJonathan great idea! And thanks @darkguy2008 and @louis-e for the code and edits!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.