Система вещания UDP не будет обмениваться данными на отдельных компьютерах

Я работаю над широковещательным маяком на С#, который должен передавать информацию о сервере всем прослушивающим устройствам. Отправляемая информация будет содержать такую ​​информацию, как URL-адрес службы WCF, пространство имен, список необходимых аргументов и т. д. Сейчас у меня есть отправитель и получатель, которые могут прекрасно общаться, когда они находятся на одном компьютере. Однако, как только я помещаю отправителя на другой компьютер, а не на компьютер получателя, отправитель отправляет свое сообщение, но мой получатель никогда его не получает. Никаких исключений не возникает, и брандмауэр отключен на обеих машинах.

http://codeidol.com/csharp/csharp-network/IP-Multicasting/What-Is-Broadcasting/ — вот откуда я взял свой код.

Отправитель:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;

namespace UDPTest
{
    class Program
    {
        static void Main(string[] args)
        {
            Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram,
            ProtocolType.Udp);
            sock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);
            IPEndPoint iep = new IPEndPoint(IPAddress.Broadcast, 9050);
            byte[] data = Encoding.ASCII.GetBytes("This is a test message");
            sock.SendTo(data, iep);
            sock.Close();
        }
    }
}

Получатель:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;

namespace UDPBroadcastReciever
{
    class Program
    {
        static void Main(string[] args)
        {
            Socket sock = new Socket(AddressFamily.InterNetwork,
            SocketType.Dgram, ProtocolType.Udp);
            IPEndPoint iep = new IPEndPoint(IPAddress.Any, 9050);
            sock.Bind(iep);
            EndPoint ep = (EndPoint)iep;
            Console.WriteLine("Ready to recieve");
            byte[] data = new byte[1024];
            int recv = sock.ReceiveFrom(data, ref ep);
            string stringData = Encoding.ASCII.GetString(data, 0, recv);
            Console.WriteLine("Received: {0} from: {1}", stringData, ep.ToString());
            sock.Close();
            Console.ReadLine();
        }
    }
}

Кто-нибудь знает что-нибудь, что я упустил, что позволило бы этим двоим разговаривать на двух разных компьютерах? Они находятся в одной подсети (192.168.1.x)

Спасибо, Ник Лонг.


person nick    schedule 23.02.2012    source источник
comment
Я считаю, что не каждый маршрутизатор будет пересылать широковещательные пакеты. Возможно, вы можете проверить это с помощью другого приложения, которое, как известно, работает.   -  person usr    schedule 24.02.2012
comment
У вас есть предложение по примерной программе?   -  person nick    schedule 24.02.2012
comment
Также проверьте C:\Windows\System32\LogFiles\Firewall и посмотрите, не блокирует ли профиль сетевых настроек порт, на который вы транслируете   -  person JeremyK    schedule 24.02.2012
comment
Также предложил бы использовать wireshark, чтобы убедиться, что вы получаете сообщение   -  person JeremyK    schedule 24.02.2012
comment
В каталоге logfiles ничего нет. Когда я копирую/вставляю найденный код msdn.microsoft.com/en-us/ library/tst0kwb1.aspx там все работает нормально.   -  person nick    schedule 24.02.2012
comment
@nick Может быть, потому что вы вещаете на 255.255.255.255 (IPAddress.Broadcast) в своем коде, а код на этой странице вещает на 192.168.1.255.   -  person spencercw    schedule 24.02.2012
comment
@spencercw После того, как я изменил, он отлично работает для вещания по локальной сети. Следующее, что мне нужно сделать, это чтобы оно транслировалось через Интернет, чтобы наше приложение на Android могло знать, куда загружать изображения. Изначально он был жестко закодирован, но моему боссу нужен маяк.   -  person nick    schedule 24.02.2012
comment
@ник Этого не произойдет. Многоадресные и широковещательные пакеты не выйдут из вашей внутренней сети (а если и выйдут, то остановятся в тот момент, когда попадут на маршрутизаторы вашего интернет-провайдера). Лучше всего, вероятно, настроить HTTP-сервер, к которому ваше приложение может периодически подключаться для обновления всего, что вам нужно. Конечно, если вы сделаете это, вы все равно будете жестко кодировать этот адрес, так что, вероятно, в этом нет смысла.   -  person spencercw    schedule 24.02.2012
comment
@spencercw Я так и думал. Думаю, я соберу его, а потом скажу ему, что он будет работать только в нашей внутренней сети. У нас уже есть http-сервер, на котором размещена служба, к которой он должен подключаться, с доменным именем, и местоположение приложения не изменится, поэтому я не уверен, в чем преимущество установки чего-то подобного в любом случае.   -  person nick    schedule 24.02.2012


Ответы (2)


Вероятно, вам лучше использовать многоадресную рассылку, а не широковещательную; широковещательные пакеты часто немедленно отбрасываются маршрутизаторами. Выберите IP-адрес где-нибудь в блоке 239.0.0.0/24 в качестве вашего многоадресного адреса; это зарезервировано для организации локальных сообщений, поэтому просто выберите номер из воздуха и придерживайтесь его.

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

sock.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership,
    new MulticastOption(theMulticastIp));

Дополнительную информацию об использовании многоадресной рассылки в C# можно найти здесь.

person spencercw    schedule 23.02.2012

У меня была похожая проблема, во всем коде, который я видел здесь, ничего не работало. когда я запустил свою программу, появилось окно брандмауэра, в котором сообщалось, что брандмауэр заблокировал некоторые функции.

моя проблема заключалась в том, что я нажимал «Разрешить доступ», не устанавливая флажок «Частные сети, отстой как моя домашняя или рабочая сеть». вы, конечно, можете изменить это позже в настройках брандмауэра и поставить галочку в этом поле. и на сервере, и на другой машине этот флажок должен быть установлен. По крайней мере, это то, что заставляет мою шахту работать.

Также мне пришлось изменить свой широковещательный IP-адрес, например, на 192.168.1.255. Мой роутер блокирует рекомендованные моей книгой 224.0.0.0 - 239.255.255.255;

person user3130012    schedule 14.04.2015