I'd like to sync different processes in unix environment using UDP. All the processes that need to be sync will be listening on the same port using this: How do SO_REUSEADDR and SO_REUSEPORT differ?
I tried on macOS with the following c# code without success:
using System.Net;
using System.Net.Sockets;
async Task Listen (){
try
{
IPEndPoint localpt = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 4000);
UdpClient udpServer = new UdpClient();
udpServer.ExclusiveAddressUse = false;
udpServer.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
udpServer.Client.EnableBroadcast = true;
udpServer.Client.Bind(localpt);
Console.WriteLine("listening");
while (true)
{
var msg = await udpServer.ReceiveAsync();
Console.WriteLine("Datagram received on UDP socket " + localpt);
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
void Send()
{
byte[] SYNC_DATAGRAM = "SYNC"u8.ToArray();
var client = new UdpClient();
client.EnableBroadcast = true;
client.Send(SYNC_DATAGRAM, SYNC_DATAGRAM.Length, new IPEndPoint(IPAddress.Parse("127.0.0.1"), 4000));
}
Listen();
Listen();
Thread.Sleep(1000);
Send();
Console.Read();
Only one socket receive the message and it seems that a loadbalancer is distributting the messages. How can all sockets receive the message?
We were in the correct direcection. Finally I made it work just sending to 255.255.255.255
and listening on ANY endpoint 0.0.0.0
.
Here is a working code in c#:
using System.Net;
using System.Net.Sockets;
async Task Listen (int id=0){
try
{
IPEndPoint localpt = new IPEndPoint(IPAddress.Parse("0.0.0.0"), 4000);
UdpClient udpServer = new UdpClient();
udpServer.ExclusiveAddressUse = false;
udpServer.Client.Bind(localpt);
Console.WriteLine("listening");
while (true)
{
var msg = await udpServer.ReceiveAsync();
Console.WriteLine("Datagram received on UDP socket " + id);
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
void Send()
{
byte[] SYNC_DATAGRAM = "SYNC"u8.ToArray();
var client = new UdpClient();
client.Client.EnableBroadcast = true;
client.Send(SYNC_DATAGRAM, SYNC_DATAGRAM.Length, new IPEndPoint(IPAddress.Parse("255.255.255.255"), 4000));
}
Task.Run(() => Listen(1));
Task.Run(() => Listen(2));
Task.Run(() => Listen(3));
Task.Run(() => Listen(4));
Task.Run(() => Listen(5));
Thread.Sleep(1000);
Send();
Console.Read();