Skip to content

Instantly share code, notes, and snippets.

@tombatron
Last active February 5, 2019 03:34
Show Gist options
  • Save tombatron/29b453cca967d6cb9ed96e8254186eee to your computer and use it in GitHub Desktop.
Save tombatron/29b453cca967d6cb9ed96e8254186eee to your computer and use it in GitHub Desktop.
Just messing around with multicast sockets.
using System;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Collections.ObjectModel;
using System.Threading;
namespace Prototype
{
public static class Program
{
public static void Main(string[] args)
{
using (var client = new MulticastClient("224.168.100.2", 11000))
{
client.RegisterOnReceiveHandler((b) =>
{
var message = Encoding.Unicode.GetString(b);
Console.WriteLine(message);
});
client.Start();
while (true)
{
var message = Console.ReadLine();
if (message == "exit")
{
Console.WriteLine("bye");
break;
}
else
{
client.SendMessage(Encoding.Unicode.GetBytes(message));
}
}
}
Console.WriteLine("Donezo.");
}
}
public class MulticastClient : IDisposable
{
private readonly Collection<Action<byte[]>> _onReceiveHanders = new Collection<Action<byte[]>>();
private readonly IPAddress _localIpAddress;
private readonly IPEndPoint _localEndpoint;
private readonly IPAddress _multicastAddress;
private readonly MulticastOption _multicastOption;
private readonly EndPoint _multicastEndpoint;
private Socket _multicastSocket;
private Thread _handlerThread;
private static bool shouldContinue = true;
public MulticastClient(string multicastAddress, int multicastPort)
{
_localIpAddress = GetDefaultIPAddress();
_localEndpoint = new IPEndPoint(_localIpAddress, multicastPort);
_multicastAddress = IPAddress.Parse(multicastAddress);
_multicastOption = new MulticastOption(_multicastAddress, _localIpAddress);
_multicastEndpoint = new IPEndPoint(_multicastAddress, multicastPort);
}
public void RegisterOnReceiveHandler(Action<byte[]> onReceiveHandler) => _onReceiveHanders.Add(onReceiveHandler);
public void Start()
{
_multicastSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
_multicastSocket.Bind(_localEndpoint);
_multicastSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, _multicastOption);
_handlerThread = new Thread(HandleIncomingBroadcast);
_handlerThread.Start();
}
public void SendMessage(byte[] message) =>
_multicastSocket.SendTo(message, _multicastEndpoint);
public void Dispose()
{
shouldContinue = false;
_multicastSocket.Shutdown(SocketShutdown.Both);
_multicastSocket.Close();
_multicastSocket.Dispose();
}
private void HandleIncomingBroadcast()
{
var buffer = new Byte[100];
var remoteEndpoint = (EndPoint)new IPEndPoint(IPAddress.Any, 0);
while (shouldContinue)
{
try
{
_multicastSocket.ReceiveFrom(buffer, ref remoteEndpoint);
foreach (var onReceiveHandler in _onReceiveHanders)
{
onReceiveHandler(buffer);
}
}
catch (SocketException ex)
{
Console.WriteLine(ex.Message);
shouldContinue = false;
}
buffer = new byte[100];
}
}
// https://stackoverflow.com/a/27376368/233516
private static IPAddress GetDefaultIPAddress()
{
using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, 0))
{
socket.Connect("8.8.8.8", 65530);
var endPoint = socket.LocalEndPoint as IPEndPoint;
return endPoint.Address;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment