2012-11-23 20 views
55

OKこれは数日前に把握しようとしてきたものです。 Windows Phone 7には、電話機がマルチキャストグループに参加し、グループにメッセージを送受信してお互いに話すアプリケーションがあります。注 - これは電話から電話への通信です。Windows Phone 8のUDPマルチキャストグループ

今、私はこのアプリケーションをWindows Phone 8に移植しようとしています - Visual Studio 2012の「電話機8に変換」機能を使用しています。私は電話通信に電話をテストしようとするまで。携帯電話は、グループの罰金に参加するようだ、彼らはOKデータグラムを送信します。彼らはグループに送るメッセージを受け取ることさえできますが、ハンドセットは他のハンドセットからメッセージを受信することはありません。ここで

が私のページへの背後にあるサンプルコードです:単にUDPスタックをテストするために

// 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"); 
} 

、私はMSDNからサンプルをダウンロードしhereを発見し、私は、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 - ノキアLumia 900(* 2)、ノキアLumia 800は、(* 3) のWindows Phone 8 - ノキアLumia 920(* 1)、ノキアコマルカ・ダ・リミア820(* 2)

これらはすべて最新のOSを実行しており、開発者モードです。 開発環境はWindows 8です。Visual Studio 2012 Professionalを実行している企業

電話機7以外のデバイスは問題ありません。

私が使った家庭用無線ネットワークは、「アウトボックス」の設定が変更されていない、基本的なBTブロードバンドルーターです。

明らかに、2つのネットワークが設定されている方法に問題がありますが、Windows Phone 8がUDPメッセージを実装する方法にも非常にはっきりと問題があります。

これは今私が怒っているので、どんなインプットも高く評価されます。

+1

私がマイクロソフトから持っていた最新のコメントは、これがスタックのバグに関連する可能性があるということです。現在、私は彼らからの返事を待っています。私はこの記事を更新する予定です。しかし、SendSocketRequest実装の最初の行が次のように変更されていれば、WinRT実装を動作させることができます: 'var stream = await socket.GetOutputStreamAsync(new Windows.Networking.HostName(IPAddress.Broadcast.ToString())、GROUP_PORT .ToString()); ' –

+0

"239.0.0.11"のような異なるグループアドレスを使用してみてください。 – nucleons

+0

Microsoftの言葉は何もありませんか?私は同じ問題を抱えており、回避策を見つけていません。 – briandunnington

答えて

1

ループバックを使用していることがわかりました。私はあなたがあなたのクライアントからメッセージを送信するときに、あなたが送ったメッセージも受け取ることを意味すると思います。つまり、受信ハンドラが起動します。それは、一見不安にならないように受信バッファをクリアする効果があります。あなたの受信メソッドにいくつかのtry catchを入れてみて、不都合なことが起こっていないかどうかを確認してください。代わりに、共有受信バッファを使用しないでください。

1

他のマルチキャストグループに参加しようとしたことがありますか? 224.0.1.1はIANA課題の時点で使用されているようです。 hereのすべてを見つけることができます。

Windows Phone 8のサービスでは、入ってくるメッセージ(たとえば、カーネルモードで動作しているネットワークサービス)を聴くことが厳しくなり、決して転送されません。

1

あなたはWindowsの携帯電話ここでは8

のために同じことをチェックアウトする必要がありますので、UDPマルチキャストは、私の経験からのWindows Phone 7の下で、かなり不思議な作品は、私の経験です:

  1. は、例えば、公式にサポートされているかどうか確認しますWindows Phone OS 7.1(切り替え前に最後に試したOS)では、TCPユニキャスト、UDPユニキャスト、UDPマルチキャストクライアントがサポートされています。
  2. Windows Phoneの一部のバージョンでは、クライアントが最初に開かれ、セッションが10秒以内に受信された場合にのみUDPセッションを受信できます。これはWindows Phoneのセキュリティのようなものです。
  3. 別のアドレスで試してください:224.0.0.0から224.0.0.255までの範囲のマルチキャストアドレスは、「よく知られている」予約されたマルチキャストアドレスです。
  4. 仮想マシンと実際の電話機の両方をチェックすると、動作が異なる場合があります。
関連する問題