aboutsummaryrefslogtreecommitdiff
path: root/Tools/Hazel-Networking/Hazel/Udp/UdpBroadcaster.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Tools/Hazel-Networking/Hazel/Udp/UdpBroadcaster.cs')
-rw-r--r--Tools/Hazel-Networking/Hazel/Udp/UdpBroadcaster.cs127
1 files changed, 127 insertions, 0 deletions
diff --git a/Tools/Hazel-Networking/Hazel/Udp/UdpBroadcaster.cs b/Tools/Hazel-Networking/Hazel/Udp/UdpBroadcaster.cs
new file mode 100644
index 0000000..8877f86
--- /dev/null
+++ b/Tools/Hazel-Networking/Hazel/Udp/UdpBroadcaster.cs
@@ -0,0 +1,127 @@
+using Hazel.UPnP;
+using System;
+using System.Net;
+using System.Net.Sockets;
+using System.Text;
+
+namespace Hazel.Udp
+{
+ public class UdpBroadcaster : IDisposable
+ {
+ private SocketBroadcast[] socketBroadcasts;
+ private byte[] data;
+ private Action<string> logger;
+
+ ///
+ public UdpBroadcaster(int port, Action<string> logger = null)
+ {
+ this.logger = logger;
+
+ var addresses = NetUtility.GetAddressesFromNetworkInterfaces(AddressFamily.InterNetwork);
+ this.socketBroadcasts = new SocketBroadcast[addresses.Count > 0 ? addresses.Count : 1];
+
+ int count = 0;
+ foreach (var addressInformation in addresses)
+ {
+ Socket socket = CreateSocket(new IPEndPoint(addressInformation.Address, 0));
+ IPAddress broadcast = NetUtility.GetBroadcastAddress(addressInformation);
+
+ this.socketBroadcasts[count] = new SocketBroadcast(socket, new IPEndPoint(broadcast, port));
+ count++;
+ }
+ if (count == 0)
+ {
+ Socket socket = CreateSocket(new IPEndPoint(IPAddress.Any, 0));
+
+ this.socketBroadcasts[0] = new SocketBroadcast(socket, new IPEndPoint(IPAddress.Broadcast, port));
+ }
+ }
+
+ private static Socket CreateSocket(IPEndPoint endPoint)
+ {
+ var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
+ socket.EnableBroadcast = true;
+ socket.MulticastLoopback = false;
+ socket.Bind(endPoint);
+
+ return socket;
+ }
+
+ ///
+ public void SetData(string data)
+ {
+ int len = UTF8Encoding.UTF8.GetByteCount(data);
+ this.data = new byte[len + 2];
+ this.data[0] = 4;
+ this.data[1] = 2;
+
+ UTF8Encoding.UTF8.GetBytes(data, 0, data.Length, this.data, 2);
+ }
+
+ ///
+ public void Broadcast()
+ {
+ if (this.data == null)
+ {
+ return;
+ }
+
+ foreach (SocketBroadcast socketBroadcast in this.socketBroadcasts)
+ {
+ try
+ {
+ Socket socket = socketBroadcast.Socket;
+ socket.BeginSendTo(data, 0, data.Length, SocketFlags.None, socketBroadcast.Broadcast, this.FinishSendTo, socket);
+ }
+ catch (Exception e)
+ {
+ this.logger?.Invoke("BroadcastListener: " + e);
+ }
+ }
+ }
+
+ private void FinishSendTo(IAsyncResult evt)
+ {
+ try
+ {
+ Socket socket = (Socket)evt.AsyncState;
+ socket.EndSendTo(evt);
+ }
+ catch (Exception e)
+ {
+ this.logger?.Invoke("BroadcastListener: " + e);
+ }
+ }
+
+ ///
+ public void Dispose()
+ {
+ if (this.socketBroadcasts != null)
+ {
+ foreach (SocketBroadcast socketBroadcast in this.socketBroadcasts)
+ {
+ Socket socket = socketBroadcast.Socket;
+ if (socket != null)
+ {
+ try { socket.Shutdown(SocketShutdown.Both); } catch { }
+ try { socket.Close(); } catch { }
+ try { socket.Dispose(); } catch { }
+ }
+ }
+ Array.Clear(this.socketBroadcasts, 0, this.socketBroadcasts.Length);
+ }
+ }
+
+ private struct SocketBroadcast
+ {
+ public Socket Socket;
+ public IPEndPoint Broadcast;
+
+ public SocketBroadcast(Socket socket, IPEndPoint broadcast)
+ {
+ Socket = socket;
+ Broadcast = broadcast;
+ }
+ }
+ }
+} \ No newline at end of file