Как сделать многоадресную рассылку UDP по локальной сети в C#?

Я пытаюсь получить простую UDP-связь, работающую в моей локальной сети.

все, что я хочу сделать, это сделать многоадресную рассылку на все машины в сети

вот мой код отправки

    public void SendMessage(string message)
    {
        var data = Encoding.Default.GetBytes(message);
        using (var udpClient = new UdpClient(AddressFamily.InterNetwork))
        {
            var address = IPAddress.Parse("224.100.0.1");
            var ipEndPoint = new IPEndPoint(address, 8088);
            udpClient.JoinMulticastGroup(address);
            udpClient.Send(data, data.Length, ipEndPoint);
            udpClient.Close();
        }
    }

и вот мой принимающий код

    public void Start()
    {
        udpClient = new UdpClient(8088);
        udpClient.JoinMulticastGroup(IPAddress.Parse("224.100.0.1"), 50);

        receiveThread = new Thread(Receive);
        receiveThread.Start();
    }

    public void Receive()
    {
        while (true)
        {
            var ipEndPoint = new IPEndPoint(IPAddress.Any, 0);
            var data = udpClient.Receive(ref ipEndPoint);

            Message = Encoding.Default.GetString(data);

            // Raise the AfterReceive event
            if (AfterReceive != null)
            {
                AfterReceive(this, new EventArgs());
            }
        }
    }

Он отлично работает на моей локальной машине, но не через сеть.

-похоже, это не брандмауэр. Я отключил его на обеих машинах, и он все еще не работал.

- It работает, если я делаю прямую отправку на жестко закодированный IP-адрес клиентской машины (т. е. не многоадресную рассылку).

любая помощь будет оценили.

3 ответов


поддерживает ли ваше оборудование локальной сети IGMP?

возможно, что ваш коммутатор знает многоадресную рассылку, но если IGMP отключен, он не заметит, подписывается ли какое-либо подключенное оборудование на определенную группу многоадресной рассылки, поэтому он не будет пересылать эти пакеты.

чтобы проверить это, временно подключите две машины непосредственно вместе с перекрестным кабелем. Это должно (AFAICR) всегда работать.

кроме того, это должно быть сервер половина кода, который имеет аргумент TTL, предоставленный JoinMulticastGroup(), не клиентская половина.


Я только что потратил 4 часа на что-то подобное (я думаю), решение для меня было:

client.Client.Bind(new IPEndPoint(IPAddress.Any, SSDP_PORT));
client.JoinMulticastGroup(SSDP_IP,IP.ExternalIPAddresses.First());
client.MulticastLoopback = true;

использование определенного (первого внешнего) IP-адреса в группе многоадресной рассылки.


Я не вижу TTL указано в любом месте в коде. Помните, что TTL изначально должен был быть в единицах секунд, но стал единицей прыжков. Это означает, что с помощью умного TTL вы можете устранить прохождение через маршрутизатор. TTL по умолчанию на моей машине-32 - я думаю, что это должно быть более чем достаточно; но ваш может быть другим (UdpClient.Ttl), если ваша система прошла через любую форму блокировки безопасности.

Я не могу рекомендовать TTL вам нужно - как и мне лично нужно сделать много экспериментов.

Если это не работает, вы можете взглянуть на эти статьи:

All-in-all похоже, что был успех с использованием сокетов, а не UdpClients.

выбранная группа многоадресной рассылки также может быть локальной. попробуйте другой.

ваш физический сетевой уровень также может вызывать проблемы. Я бы рискнул подвергнуть сомнению коммутаторы и прямые (x-over) соединения. Концентраторы и все более умные должны справляться с ними отлично. Однако у меня нет никакой литературы, подтверждающей это.