Here's my code... I've tried many things, but none of them work. I'm sure there's something I'm missing. The intent is that a client listens to the given _remoteEndpoint address. Instead, nothing is found at all, despite showing the broadcast in Wireshark, windump, etc. The ports are open, firewall disabled and so on. I tried our legacy code 1:1 and it also didn't work, but it works in the old binaries without issue. Did something change from .NET 4 to .NET 6 with how this functions?
This is on Windows of various versions.
using System;
using System.Net.Sockets;
using System.Net;
using Easy.Logger.Interfaces;
using Easy.Logger;
using MktSrvcAPI.Sockets;
using RBClients.SprdClient;
namespace SpreadFeedPubSub.DAL
{
public class MulticastEndpoint
{
private static readonly IEasyLogger log = Log4NetService.Instance.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
public int AssociatedFilterId { get; private set; }
public string AssociatedFilterName { get; private set; }
public IPAddress Address { get; private set; }
public int Port { get; private set; }
private IPEndPoint _remoteEndpoint;
public Socket MulticastClient { get; private set; }
public ByteBuffer Buffer { get; private set; }
public string Protocol { get; private set; }
private int _maxBufferSize;
public MulticastEndpoint(string ip, int port, int associatedFilter = -1, int bufferSize = 2048)
{
Address = IPAddress.Parse(ip);
Port = port;
_remoteEndpoint = new IPEndPoint(Address, Port);
_maxBufferSize = Math.Min(bufferSize, 2048);
Buffer = new ByteBuffer(_maxBufferSize);
AssociatedFilterId = associatedFilter;
}
public void SendData(Message data)
{
if (data == null)
{
return;
}
lock (Buffer)
{
if (Buffer.UnusedLength < data.Length)
{
SendBuffer();
}
Buffer.Append(data.Bytes, 0, data.Length);
}
}
public void SendBuffer()
{
if (Buffer.SIZE == Buffer.UnusedLength)
{
return;
}
MulticastClient.SendTo(Buffer.DATA, _remoteEndpoint);
Buffer.Clear();
}
public void Close()
{
try
{
MulticastClient.Close();
MulticastClient.Dispose();
}
catch (Exception ex)
{
//log.Error($"StartConnection {IP}:{Port} - " + ex.ToString());
}
}
public void Create()
{
try
{
MulticastClient = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
MulticastClient.ExclusiveAddressUse = false;
MulticastClient.EnableBroadcast = true;
MulticastClient.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(Address, Program.IFACE_HOST));
MulticastClient.Bind(new IPEndPoint(Program.IFACE_HOST, Port));
}
catch (SocketException se)
{
//log.Error($"StartConnection {IP}:{Port} - " + se.ToString());
if (se.ErrorCode == 10048)
{
log.Error("Socket already being used.");
}
throw (se);
}
catch (Exception ex)
{
//log.Error($"StartConnection {IP}:{Port} - " + ex.ToString());
throw (ex);
}
}
}
}
What I've tried
- UdpClient with JoinMulticast, exclusiveaddress false, broadcast true, Send to _remoteEndpoint.
- Socket with and without options, with and without exclusiveaddress, broadcast, with and without Bind.
The issue was TTL. Setting the TimeToLive to 15 fixed it.
MulticastClient.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, 15);