Самое простое размещение рекламы / прослушивания через сокеты

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

string Port = "54153";
HostName Host = new HostName("224.3.0.5"); //a multicast range address

//listener
var L = new DatagramSocket();
L.MessageReceived += (sender2, args) => { /*something*/ };
await L.BindServiceNameAsync(Port);
L.JoinMulticastGroup(Host);

//advertiser
var AdvertiserSocket = new DatagramSocket();
AdvertiserSocket.Control.MulticastOnly = true;

Stream outStream = (await AdvertiserSocket.GetOutputStreamAsync(Host, Port)).AsStreamForWrite();
using (var writer = new StreamWriter(outStream))
{
  await writer.WriteLineAsync("MESSAGE");
  await writer.FlushAsync();
}

Слушатель вообще ничего не получает (MessageReceived никогда не вызывается). Я попробовал следующие варианты без успеха:

  1. Вызов, а не вызов BindServiceNameAsync() для рекламодателя.
  2. С помощью MulticastOnly на рекламодателя, слушателя или оба
  3. Ожидание в течение нескольких секунд после создания одного объекта перед другим.
  4. С помощью 255.255.255.255 как хозяин.

1 ответ

Решение

Похоже, что рекламодатель правильно передает данные в многоадресном режиме (TCPView показывает отправленные пакеты), но принимающий порт ничего не получает.

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

Итак, в настоящее время обходной путь заключается в отправке пустого сообщения сразу после регистрации для прослушивания:

private async void btnListen_Click(object sender, RoutedEventArgs e)
{
        socket = new DatagramSocket();
        socket.MessageReceived += Socket_MessageReceived;
        socket.Control.MulticastOnly = true;
        await socket.BindServiceNameAsync(serverPort);
        socket.JoinMulticastGroup(serverHost);
        SendWithExistingSocket(socket, "");//send an empty message immediately
}

private async void SendWithExistingSocket(DatagramSocket socket, String text)
{
    if (socket != null)
    {
        Stream stream = (await socket.GetOutputStreamAsync(serverHost, serverPort)).AsStreamForWrite();
        using (var writer = new StreamWriter(stream))
        {
            writer.WriteLine(text);
            await writer.FlushAsync();
        }
    }
}

Что касается основной причины этой проблемы, я проконсультируюсь с соответствующей командой и сообщу, как только я получу ответ.

Другие вопросы по тегам