Подтвердить что ты не робот

Многоадресная группа 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, и снова вижу успешное инициирование, но не взаимодействие между устройствами.

Это тот же код за страницей с использованием реализации сокета datagram:

// 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 Broadband без изменения настроек "вне коробки".

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

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

4b9b3361

Ответ 1

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

Ответ 2

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

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

Ответ 3

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

Вот мой опыт:

  • проверьте, что официально поддерживается, например, в Windows Phone OS 7.1 (последняя ОС, которую я пробовал перед переключением), поддерживаются одноадресная рассылка одноадресной рассылки, одноадресная передача UDP и многоадресные клиенты UDP.
  • некоторые версии телефона Windows разрешают получать сеанс UDP только в том случае, если клиент первым открыл его и сеанс был получен не более чем через 10 секунд, это похоже на какую-то вещь безопасности на Windows Phone.
  • попробуйте использовать разные адреса: многоадресные адреса в диапазоне от 224.0.0.0 до 224.0.0.255 включительно являются "хорошо известными" зарезервированными многоадресными адресами.
  • Проверьте как на виртуальной машине, так и на реальном телефоне, поведение может отличаться.