Last active
February 5, 2019 03:34
-
-
Save tombatron/29b453cca967d6cb9ed96e8254186eee to your computer and use it in GitHub Desktop.
Just messing around with multicast sockets.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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