Группа многоадресной рассылки UDP на Windows Phone 8

Хорошо, это то, что я пытался выяснить уже несколько дней. У нас есть приложение для Windows Phone 7, в котором телефоны присоединяются к группе многоадресной рассылки, а затем отправляют и получают сообщения в группу, чтобы общаться друг с другом. Примечание. Это общение по телефону с телефоном.

Теперь я пытаюсь перенести это приложение на Windows Phone 8 - используя функцию «Преобразовать в телефон 8» в Visual Studio 2012 - пока все хорошо. Пока не попробую проверить телефон на телефонную связь. Трубки вроде нормально присоединяются к группе и отправляют дейтаграммы нормально. Они даже получают сообщения, которые отправляют группе, однако ни один телефон никогда не получает сообщения от другого телефона.

Вот пример кода моей страницы:

// Constructor
public MainPage()
{
    InitializeComponent();
}

// The address of the multicast group to join.
// Must be in the range from 224.0.0.0 to 239.255.255.255
private const string GROUP_ADDRESS = "224.0.1.1";

// The port over which to communicate to the multicast group
private const int GROUP_PORT = 55562;

// A client receiver for multicast traffic from any source
UdpAnySourceMulticastClient _client = null;

// Buffer for incoming data
private byte[] _receiveBuffer;

// Maximum size of a message in this communication
private const int MAX_MESSAGE_SIZE = 512;

private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
{
    _client = new UdpAnySourceMulticastClient(IPAddress.Parse(GROUP_ADDRESS), GROUP_PORT);
    _receiveBuffer = new byte[MAX_MESSAGE_SIZE];

    _client.BeginJoinGroup(
        result =>
        {
            _client.EndJoinGroup(result);
            _client.MulticastLoopback = true;
            Receive();
        }, null);
}

private void SendRequest(string s)
{
    if (string.IsNullOrWhiteSpace(s)) return;

    byte[] requestData = Encoding.UTF8.GetBytes(s);

    _client.BeginSendToGroup(requestData, 0, requestData.Length,
        result =>
        {
            _client.EndSendToGroup(result);
            Receive();
        }, null);
}

private void Receive()
{
    Array.Clear(_receiveBuffer, 0, _receiveBuffer.Length);
    _client.BeginReceiveFromGroup(_receiveBuffer, 0, _receiveBuffer.Length,
        result =>
        {
            IPEndPoint source;

            _client.EndReceiveFromGroup(result, out source);

            string dataReceived = Encoding.UTF8.GetString(_receiveBuffer, 0, _receiveBuffer.Length);

            string message = String.Format("[{0}]: {1}", source.Address.ToString(), dataReceived);
            Log(message, false);

            Receive();
        }, null);
}

private void Log(string message, bool isOutgoing)
{
    if (string.IsNullOrWhiteSpace(message.Trim('\0')))
    {
        return;
    }

    // Always make sure to do this on the UI thread.
    Deployment.Current.Dispatcher.BeginInvoke(
    () =>
    {
        string direction = (isOutgoing) ? ">> " : "<< ";
        string timestamp = DateTime.Now.ToString("HH:mm:ss");
        message = timestamp + direction + message;
        lbLog.Items.Add(message);

        // Make sure that the item we added is visible to the user.
        lbLog.ScrollIntoView(message);
    });

}

private void btnSend_Click(object sender, RoutedEventArgs e)
{
    // Don't send empty messages.
    if (!String.IsNullOrWhiteSpace(txtInput.Text))
    {
        //Send(txtInput.Text);
        SendRequest(txtInput.Text);
    }
}

private void btnStart_Click(object sender, RoutedEventArgs e)
{
    SendRequest("start now");
}

Чтобы просто протестировать стек UDP, я загрузил образец из MSDN, найденный здесь и я протестировал это на паре устройств Windows Phone 7, и он работает должным образом. Затем я перешел на Windows Phone 8 и развернул на своих телефонах, снова кажется, что устройства инициируют свое соединение, и пользователь может ввести свое имя. Однако опять же устройства не могут видеть другие устройства или взаимодействовать с ними.

Наконец, я выполнил простой тест связи, используя новую реализацию DatagramSocket, и снова вижу успешное инициирование, но отсутствие связи между устройствами.

Это тот же код за страницей, использующий реализацию сокета дейтаграммы:

// Constructor
public MainPage()
{
    InitializeComponent();
}

// The address of the multicast group to join.
// Must be in the range from 224.0.0.0 to 239.255.255.255
private const string GROUP_ADDRESS = "224.0.1.1";

// The port over which to communicate to the multicast group
private const int GROUP_PORT = 55562;

private DatagramSocket socket = null;

private void Log(string message, bool isOutgoing)
{
    if (string.IsNullOrWhiteSpace(message.Trim('\0')))
        return;

    // Always make sure to do this on the UI thread.
    Deployment.Current.Dispatcher.BeginInvoke(
    () =>
    {
        string direction = (isOutgoing) ? ">> " : "<< ";
        string timestamp = DateTime.Now.ToString("HH:mm:ss");
        message = timestamp + direction + message;
        lbLog.Items.Add(message);

        // Make sure that the item we added is visible to the user.
        lbLog.ScrollIntoView(message);
    });
}

private void btnSend_Click(object sender, RoutedEventArgs e)
{
    // Don't send empty messages.
    if (!String.IsNullOrWhiteSpace(txtInput.Text))
    {
        //Send(txtInput.Text);
        SendSocketRequest(txtInput.Text);
    }
}

private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
{
    socket = new DatagramSocket();
    socket.MessageReceived += socket_MessageReceived;

    try
    {
        // Connect to the server (in our case the listener we created in previous step).
        await socket.BindServiceNameAsync(GROUP_PORT.ToString());
        socket.JoinMulticastGroup(new Windows.Networking.HostName(GROUP_ADDRESS));
        System.Diagnostics.Debug.WriteLine(socket.ToString());
    }
    catch (Exception exception)
    {
        throw;
    }
}

private async void SendSocketRequest(string message)
{
    // Create a DataWriter if we did not create one yet. Otherwise use one that is already cached.
    //DataWriter writer;
    var stream = await socket.GetOutputStreamAsync(new Windows.Networking.HostName(GROUP_ADDRESS), GROUP_PORT.ToString());
    //writer = new DataWriter(socket.OutputStream);
    DataWriter writer = new DataWriter(stream);

    // Write first the length of the string as UINT32 value followed up by the string. Writing data to the writer will just store data in memory.
   // stream.WriteAsync(
    writer.WriteString(message);

    // Write the locally buffered data to the network.
    try
    {
        await writer.StoreAsync();
        Log(message, true);
        System.Diagnostics.Debug.WriteLine(socket.ToString());
    }
    catch (Exception exception)
    {
        throw;
    }
    finally
    {
        writer.Dispose();
    }
}

void socket_MessageReceived(DatagramSocket sender, DatagramSocketMessageReceivedEventArgs args)
{
    try
    {
        uint stringLength = args.GetDataReader().UnconsumedBufferLength;
        string msg = args.GetDataReader().ReadString(stringLength);

        Log(msg, false);
    }
    catch (Exception exception)
    {
        throw;
    }
}

Вчера вечером я взял телефоны домой, чтобы проверить их в моей домашней беспроводной сети, низкий уровень и вот, я получаю успешную связь с устройством.

Итак, напомним, мой старый код Windows Phone 7 отлично работает в моей рабочей сети. Порт на Windows Phone 8 (без фактического изменения кода) не передает сообщения между устройствами. Этот код действительно работает в моей домашней сети. Код запускается с подключенным отладчиком, и во время выполнения нигде нет никаких признаков ошибок или исключений.

Я использую следующие телефоны:

Windows Phone 7 - Nokia Lumia 900 (* 2), Nokia Lumia 800 (* 3) Windows Phone 8 - Nokia Lumia 920 (* 1), Nokia Limia 820 (* 2)

Все они работают под управлением последней версии ОС и находятся в режиме разработчика. Среда разработки - Windows 8 Enterprise под управлением Visual Studio 2012 Professional.

Не могу много рассказать о работе беспроводной сети - кроме Phone 7 у аппаратов проблем нет.

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

Очевидно, что существует проблема с настройкой этих двух сетей, но также очень очевидна проблема с тем, как Windows Phone 8 реализует UDP-сообщения.

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


person Adam Stewart    schedule 23.11.2012    source источник
comment
Последний комментарий, который я получил от Microsoft, заключается в том, что это может быть связано с ошибкой в ​​стеке. На данный момент я жду ответа от них. Я буду обновлять этот пост, когда услышу больше. Однако реализацию WinRT можно заставить работать, если изменить первую строку реализации SendSocketRequest на это: var stream = await socket.GetOutputStreamAsync(new Windows.Networking.HostName(IPAddress.Broadcast.ToString()), GROUP_PORT.ToString());   -  person Adam Stewart    schedule 03.12.2012
comment
Попробуйте использовать другой групповой адрес, например 239.0.0.11.   -  person nucleons    schedule 17.12.2012
comment
Еще новости от Microsoft? Я сталкиваюсь с той же проблемой и не нашел решения.   -  person briandunnington    schedule 20.12.2012
comment
У меня точно такая же проблема. У вас есть новые новости ??   -  person The Chris    schedule 28.12.2012
comment
@nucleons, я больше ничего не слышал от Microsoft с тех пор, как они подтвердили, что ошибка была в их стеке. Мы используем обходной путь, описанный выше; и так как это работает, мы перешли к нашим новым элементам работы. Я буду обновлять этот пост, если я услышу что-нибудь от MS относительно решения этого вопроса.   -  person Adam Stewart    schedule 02.01.2013
comment
@ ChrisTTian667 см. Последний мой комментарий   -  person Adam Stewart    schedule 02.01.2013
comment
Я наблюдаю то же самое, а также обратился в службу поддержки Microsoft. См. Здесь: social.msdn .microsoft.com / Forums / en-US / wpdevelop / thread / Другие пользователи, также сообщающие об этом: social.msdn.microsoft.com/Forums/en-US/wpdevelop/thread/ social.msdn.microsoft.com/Forums/en-US/ wpdevelop / thread / Лично я не видел ни одной сети Wi-Fi, в которой это работает, поэтому до сих пор я предполагал, что это не проблема Wi-Fi   -  person dotMorten    schedule 04.01.2013
comment
... кстати, ваш обходной путь не сработал для меня.   -  person dotMorten    schedule 04.01.2013
comment
@dotMorten, читая ваши комментарии в других обсуждениях, я также могу подтвердить, что я все еще вижу эту ошибку и на Lumia 820s. По-прежнему нет новостей от MS, мой конец тоже   -  person Adam Stewart    schedule 15.01.2013
comment
Согласно комментарию Мортена на форумах MSDN, это должно быть исправлено с помощью обновления прошивки, опубликованного более шести месяцев назад. @AdamStewart, можете ли вы подтвердить, что это так, и если да, закройте вопрос?   -  person Claus Jørgensen    schedule 20.07.2013
comment
@ ClausJørgensen У меня больше нет доступа к коду или оборудованию, к которому относится этот вопрос, возможно, если кто-то другой, у кого возникла проблема, мог бы проверить, этот вопрос можно закрыть. Однако вы упоминаете прошивку, а не патч для программного обеспечения Windows. Я видел эту проблему на мобильных телефонах Nokia Lumia 920 и 820 и на столах Samsung, и, как упоминалось ранее, MS подтвердила, что проблема была в стеке Windows 8.   -  person Adam Stewart    schedule 22.07.2013
comment
Теперь это устарело, поскольку UdpAnySourceMulticastClient устарел. Я попытался сделать многоадресную рассылку с помощью нового DatagramSocet, но безуспешно. Есть идеи, как выполнять многоадресную рассылку с использованием новых API? API Microsoft в последнее время - беспорядок, меняются почти каждый месяц ... А документация - отстой   -  person Daniel Gruszczyk    schedule 09.05.2015


Ответы (3)


Я заметил, что вы используете возвратную петлю. Я думаю, это означает, что когда вы отправляете сообщение от своего клиента, вы также получите сообщение, которое вы отправили. Это означает, что ваш обработчик приема сработает. Это имеет эффект очистки приемного буфера, казалось бы, небезопасным для чтения способом. Попробуйте добавить try catch в свой метод приема и посмотрите, не происходит ли что-нибудь нежелательное, но вместо этого вы можете просто не использовать общий буфер приема в любом случае.

person cineam mispelt    schedule 20.08.2013

Вы когда-нибудь пробовали присоединиться к другой группе многоадресной рассылки? Потому что 224.0.1.1, похоже, используется в качестве назначений IANA. Вы найдете все здесь.

Возможно, в Windows Phone 8 какая-то служба более жестко привязана к входящим сообщениям (например, сетевая служба, работающая в режиме ядра), и они никогда не пересылаются вам.

person HaMster    schedule 13.09.2013

По моему опыту, многоадресная рассылка UDP работает довольно странно под Windows Phone 7, поэтому вы должны проверить то же самое для Windows Phone 8.

Вот мой опыт:

  1. проверьте, что официально поддерживается, например, в ОС Windows Phone 7.1 (последняя ОС, которую я пробовал перед переключением), поддерживаются клиенты одноадресной передачи TCP, одноадресной рассылки UDP и многоадресной рассылки UDP.
  2. некоторые версии Windows phone позволяют получать сеанс UDP только в том случае, если клиент сначала его открыл, и сеанс получен в течение не более 10 секунд, это похоже на какую-то вещь безопасности на Windows Phone.
  3. попробуйте с другими адресами: адреса многоадресной рассылки в диапазоне от 224.0.0.0 до 224.0.0.255 включительно являются «хорошо известными» зарезервированными адресами многоадресной рассылки.
  4. Проверяйте как на виртуальной машине, так и на реальном телефоне, поведение может отличаться.
person dendini    schedule 13.12.2013