Sockets Windows Phone 7通过wifi接收UDP数据包(广播或单播)

Sockets Windows Phone 7通过wifi接收UDP数据包(广播或单播),sockets,udp,windows-phone-7.1,asyncsocket,Sockets,Udp,Windows Phone 7.1,Asyncsocket,我已经看了好几天关于WindowsPhone7的各种论坛,但是没有一个给我一个明确的答案。 到目前为止,我还无法接收通过wifi连接到Windows Phone 7设备(在emulator上运行)的计算机发送的UDP数据包(既不是广播也不是单播) 显然,应该支持UDP单播,并且下面的代码可以正确运行,但是手机没有收到UDP数据包。 我希望有人能纠正下面的代码 请注意,以下代码遵循了迄今为止在其他论坛上给出的所有建议,即: 首先将数据包发送到指定的目的地,然后侦听应答 不使用广播,但使用UDP单播

我已经看了好几天关于WindowsPhone7的各种论坛,但是没有一个给我一个明确的答案。 到目前为止,我还无法接收通过wifi连接到Windows Phone 7设备(在emulator上运行)的计算机发送的UDP数据包(既不是广播也不是单播)

显然,应该支持UDP单播,并且下面的代码可以正确运行,但是手机没有收到UDP数据包。 我希望有人能纠正下面的代码

请注意,以下代码遵循了迄今为止在其他论坛上给出的所有建议,即:

  • 首先将数据包发送到指定的目的地,然后侦听应答
  • 不使用广播,但使用UDP单播(我可以测试这两种设置isBroadcast变量)
  • 使用SilverLight允许的端口4502
  • MainPage.xaml

       <phone:PhoneApplicationPage 
          x:Class="UDPClient.MainPage"
          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
          xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
          xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
          xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
          xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
          mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"
          FontFamily="{StaticResource PhoneFontFamilyNormal}"
          FontSize="{StaticResource PhoneFontSizeNormal}"
          Foreground="{StaticResource PhoneForegroundBrush}"
          SupportedOrientations="Portrait" Orientation="Portrait"
          shell:SystemTray.IsVisible="True">
    
          <!--LayoutRoot is the root grid where all page content is placed-->
          <Grid x:Name="LayoutRoot" Background="Transparent">
              <Grid.RowDefinitions>
              <RowDefinition Height="Auto"/>
              <RowDefinition Height="*"/>
              </Grid.RowDefinitions>
    
          <!--TitlePanel contains the name of the application and page title-->
              <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
              <TextBlock x:Name="ApplicationTitle" Text="UDP Socket Application" Style="{StaticResource PhoneTextNormalStyle}"/>
              <TextBlock x:Name="PageTitle" Text="Client" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
              </StackPanel>
    
    
              <!--ContentPanel - place additional content here-->
              <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,-8,12,8">
              <Grid.ColumnDefinitions>
                  <ColumnDefinition Width="Auto"/>
                  <!-- Fit to content -->
                  <ColumnDefinition Width="Auto"/>
                  <!-- Fit to content -->
                  <ColumnDefinition Width="Auto"/>
                  <!-- Fit to content -->
                  <ColumnDefinition Width="*"/>
                  <!-- Take up remaining space -->
              </Grid.ColumnDefinitions>
              <Grid.RowDefinitions>
                  <RowDefinition Height="Auto"/>
                  <!-- Fit to content -->
                  <RowDefinition Height="Auto"/>
                  <!-- Fit to content -->
                  <RowDefinition Height="Auto"/>
                  <!-- Fit to content -->
                  <RowDefinition Height="*"/>
                  <!-- Take up remaining space -->
              </Grid.RowDefinitions>
    
              <!-- Grid Row 0: Remote Host Input Field >-->
              <TextBlock Grid.Row="0" Grid.Column="0" Text="Host Name:"  
                    VerticalAlignment="Center" HorizontalAlignment="Center" 
                    FontSize="{StaticResource PhoneFontSizeNormal}" />
              <TextBox x:Name="txtRemoteHost" Grid.Row="0" Grid.Column="1"  Height="70" Width="200" 
                  VerticalAlignment="Top" HorizontalAlignment="Left" 
                  FontSize="{StaticResource PhoneFontSizeNormal}" Text="192.168.1.3" />
    
              <!-- Grid Row 1: Echo >-->
              <!-- TextBlock for Echo command label-->
              <TextBlock Grid.Row="1" Grid.Column="0" Text="Text To Echo:" 
                    VerticalAlignment="Center" HorizontalAlignment="Center" 
                    FontSize="{StaticResource PhoneFontSizeNormal}" />
    
              <!-- TextBox for Echo command text input-->
              <TextBox x:Name="txtInput" Grid.Row="1" Grid.Column="1" Height="70" Width="200"  
                  VerticalAlignment="Top" HorizontalAlignment="Left" 
                  FontSize="{StaticResource PhoneFontSizeNormal}" Text="test..." />
    
              <!-- Button to the right of the input textbox for the Echo command >-->
              <Button x:Name="btnEcho" Grid.Row="1" Grid.Column="2" Height="70"  Width="120" 
                  Content="Echo" 
                  FontSize="{StaticResource PhoneFontSizeNormal}" Click="btnEcho_Click"/>
    
              <!-- Grid Row 2: Quote of the Day-->
              <!-- Button for the Quote command >-->
              <Button x:Name="btnGetQuote" Grid.Row="2" Grid.ColumnSpan="4" Height="70" 
                  Content="Get Quote of the Day" 
                  FontSize="{StaticResource PhoneFontSizeNormal}" Click="btnGetQuote_Click"/>
              <!-- Grid Row 3: Output-->
              <!-- Output TextBox named 'txtOutput' >-->
              <TextBox x:Name="txtOutput" Grid.Row="3" Grid.ColumnSpan="4" Background="Black" BorderBrush="Green" 
                  AcceptsReturn="False" Foreground="LightGray" FontFamily="Courier New"  
                  IsHitTestVisible="False" FontSize="{StaticResource PhoneFontSizeSmall}" TextWrapping="Wrap" />
              <Button Content="Listen" Grid.Column="1" Grid.ColumnSpan="2" Height="70" HorizontalAlignment="Left" Margin="195,0,0,0" Name="Listenbutton" VerticalAlignment="Top" Width="125" Click="Listenbutton_Click" />
              </Grid>
          </Grid>
    
          <!--Sample code showing usage of ApplicationBar-->
          <!--<phone:PhoneApplicationPage.ApplicationBar>
              <shell:ApplicationBar IsVisible="True" IsMenuEnabled="True">
              <shell:ApplicationBarIconButton IconUri="/Images/appbar_button1.png" Text="Button 1"/>
              <shell:ApplicationBarIconButton IconUri="/Images/appbar_button2.png" Text="Button 2"/>
              <shell:ApplicationBar.MenuItems>
                  <shell:ApplicationBarMenuItem Text="MenuItem 1"/>
                  <shell:ApplicationBarMenuItem Text="MenuItem 2"/>
              </shell:ApplicationBar.MenuItems>
              </shell:ApplicationBar>
          </phone:PhoneApplicationPage.ApplicationBar>-->
    
          </phone:PhoneApplicationPage>
    
    
    
    MainPage.xaml.cs

      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Net;
      using System.Windows;
      using System.Windows.Controls;
      using System.Windows.Documents;
      using System.Windows.Input;
      using System.Windows.Media;
      using System.Windows.Media.Animation;
      using System.Windows.Shapes;
      using Microsoft.Phone.Controls;
      using System.Net.Sockets;
      using System.Threading;
    
    
      namespace UDPClient
      {
      public partial class MainPage : PhoneApplicationPage
      {
      // Constructor
      public MainPage()
      {
      InitializeComponent();
      }
    
      // Constants
      const int ECHO_PORT = 7;  // The Echo protocol uses port 7 in this sample
      const int QOTD_PORT = 17; // The Quote of the Day (QOTD) protocol uses port 17 in this sample
      const int UDP_PORT = 4502;
      /// <summary>
      /// Handle the btnEcho_Click event by sending text to the echo server and outputting the response
      /// </summary>
      private void btnEcho_Click(object sender, RoutedEventArgs e)
      {
      // Clear the log 
      ClearLog();
    
      // Make sure we can perform this action with valid data
      if (ValidateRemoteHost() && ValidateInput())
      {
          // Instantiate the SocketClient
          SocketClient client = new SocketClient();
          SocketAsyncEventArgs socketEventArg; 
    
          // Attempt to send our message to be echoed to the echo server
          Log(String.Format("Sending '{0}' to server ...", txtInput.Text), true);
          string result = client.Send(txtRemoteHost.Text, ECHO_PORT, txtInput.Text, false, out socketEventArg);
          Log(result, false);
    
          // Receive a response from the echo server
          Log("Requesting Receive ...", true);
          result = client.UDPReceive(ECHO_PORT, false);
          Log(result, false);
    
          // Close the socket connection explicitly
          client.Close();
      }
    
      }
    
      private void Listenbutton_Click(object sender, RoutedEventArgs e)
      {
      // Clear the log 
      ClearLog();
    
      // Make sure we can perform this action with valid data
      if (ValidateRemoteHost())
      {
          // Instantiate the SocketClient
          SocketClient client = new SocketClient();
    
          // Receive packets
          string result = client.UDPReceive(UDP_PORT, false);
          Log(result, false);
          // Close the socket connection explicitly
          client.Close();
      }
      }
    
      /// <summary>
      /// Handle the btnGetQuote_Click event by receiving text from the Quote of the Day (QOTD) server and outputting the response
      /// </summary>
      private void btnGetQuote_Click(object sender, RoutedEventArgs e)
      {
      // Clear the log 
      ClearLog();
      // Receive response from the QOTD server
      Log("nothing...", true);;
      }
      }
    
      #region UI Validation
      /// <summary>
      /// Validates the txtInput TextBox
      /// </summary>
      /// <returns>True if the txtInput TextBox contains valid data, False otherwise</returns>
      private bool ValidateInput()
      {
      // txtInput must contain some text
      if (String.IsNullOrWhiteSpace(txtInput.Text))
      {
          MessageBox.Show("Please enter some text to echo");
          return false;
      }
    
      return true;
      }
    
      /// <summary>
      /// Validates the txtRemoteHost TextBox
      /// </summary>
      /// <returns>True if the txtRemoteHost contains valid data, False otherwise</returns>
      private bool ValidateRemoteHost()
      {
      // The txtRemoteHost must contain some text
      if (String.IsNullOrWhiteSpace(txtRemoteHost.Text))
      {
          MessageBox.Show("Please enter a host name");
          return false;
      }
    
      return true;
      }
      #endregion
    
      #region Logging
      /// <summary>
      /// Log text to the txtOutput TextBox
      /// </summary>
      /// <param name="message">The message to write to the txtOutput TextBox</param>
      /// <param name="isOutgoing">True if the message is an outgoing (client to server) message, False otherwise</param>
      /// <remarks>We differentiate between a message from the client and server 
      /// by prepending each line  with ">>" and "<<" respectively.</remarks>
      private void Log(string message, bool isOutgoing)
      {
      string direction = (isOutgoing) ? ">> " : "<< ";
      txtOutput.Text += Environment.NewLine + direction + message;
      }
    
      /// <summary>
      /// Clears the txtOutput TextBox
      /// </summary>
      private void ClearLog()
      {
      txtOutput.Text = String.Empty;
      }
      #endregion
    }
    }
    
    使用系统;
    使用System.Collections.Generic;
    使用System.Linq;
    Net系统;
    使用System.Windows;
    使用System.Windows.Controls;
    使用System.Windows.Documents;
    使用System.Windows.Input;
    使用System.Windows.Media;
    使用System.Windows.Media.Animation;
    使用System.Windows.Shapes;
    使用Microsoft.Phone.Controls;
    使用System.Net.Sockets;
    使用系统线程;
    命名空间UDPClient
    {
    公共部分类主页:PhoneApplicationPage
    {
    //建造师
    公共主页()
    {
    初始化组件();
    }
    //常数
    const int ECHO_PORT=7;//ECHO协议在此示例中使用端口7
    const int QOTD_PORT=17;//在本示例中,当日报价(QOTD)协议使用端口17
    常量int UDP_端口=4502;
    /// 
    ///通过向echo服务器发送文本并输出响应来处理btnEcho_Click事件
    /// 
    私有无效btnEcho_单击(对象发送者,路由目标e)
    {
    //清除日志
    ClearLog();
    //确保我们可以使用有效数据执行此操作
    if(ValidateRemoteHost()&&ValidateInput())
    {
    //实例化SocketClient
    SocketClient=new SocketClient();
    SocketAsyncEventArgs socketEventArg;
    //尝试将我们的邮件发送到回显服务器
    日志(String.Format(“将{0}发送到服务器…”,txtInput.Text),true);
    字符串结果=client.Send(txtmotehost.Text,ECHO_端口,txtInput.Text,false,out socketEventArg);
    日志(结果,假);
    //从echo服务器接收响应
    日志(“请求接收…”,true);
    结果=client.udprective(ECHO_端口,false);
    日志(结果,假);
    //显式关闭套接字连接
    client.Close();
    }
    }
    私有无效列表按钮单击(对象发送者,路由目标)
    {
    //清除日志
    ClearLog();
    //确保我们可以使用有效数据执行此操作
    if(ValidateRemoteHost())
    {
    //实例化SocketClient
    SocketClient=new SocketClient();
    //接收数据包
    字符串结果=client.udprective(UDP_端口,false);
    日志(结果,假);
    //显式关闭套接字连接
    client.Close();
    }
    }
    /// 
    ///通过接收来自当日报价(QOTD)服务器的文本并输出响应来处理btnGetQuote_Click事件
    /// 
    私有无效btnGetQuote\U单击(对象发送者,路由目标e)
    {
    //清除日志
    ClearLog();
    //从QOTD服务器接收响应
    日志(“无…”,正确);;
    }
    }
    #区域用户界面验证
    /// 
    ///验证txtInput文本框
    /// 
    ///如果txtInput文本框包含有效数据,则为True,否则为False
    私有bool ValidateInput()
    {
    //txtInput必须包含一些文本
    if(String.IsNullOrWhiteSpace(txtInput.Text))
    {
    MessageBox.Show(“请输入一些要回显的文本”);
    返回false;
    }
    返回true;
    }
    /// 
    ///验证txtRemoteHost文本框
    /// 
    ///如果txtRemoteHost包含有效数据,则为True,否则为False
    私有bool ValidateRemoteHost()
    {
    //txtRemoteHost必须包含一些文本
    if(String.IsNullOrWhiteSpace(txtmotehost.Text))
    {
    MessageBox.Show(“请输入主机名”);
    返回false;
    }
    返回true;
    }
    #端区
    #区域测井
    /// 
    ///将文本记录到TXT输出文本框
    /// 
    ///要写入TXT输出文本框的消息
    ///如果消息是传出(客户端到服务器)消息,则为True,否则为False
    ///我们区分来自客户端和服务器的消息
    
    ///通过在每行前面加“>>”和“>”:“端口4502在Silverlight for Windows Phone中不是必需的,但仅在Silverlight for browser应用程序中是必需的。我正在检查您的代码,因为我有同样的问题。

    您是在设备上还是在模拟器上运行它?
      using System;
      using System.Net;
      using System.Windows;
      using System.Windows.Controls;
      using System.Windows.Documents;
      using System.Windows.Ink;
      using System.Windows.Input;
      using System.Windows.Media;
      using System.Windows.Media.Animation;
      using System.Windows.Shapes;
      using System.Net.Sockets;
      using System.Threading;
      using System.Text;
    
      namespace UDPClient
      {
      public class SocketClient
      {
      // Cached Socket object that will be used by each call for the lifetime of this class
      Socket _socket = null;
      // Signaling object used to notify when an asynchronous operation is completed
      static ManualResetEvent _clientDone = new ManualResetEvent(false);
      // Define a timeout in milliseconds for each asynchronous call. If a response is not received within this 
      // timeout period, the call is aborted.
      const int TIMEOUT_MILLISECONDS = 1000;
      // The maximum size of the data buffer to use with the asynchronous socket methods
      const int MAX_BUFFER_SIZE = 2048;
      bool isHasSent = false;
      int errorCode = 0;
    
      /// <summary>
      /// SocketClient Constructor
      /// </summary>
      public SocketClient()
      {
      // The following creates a socket with the following properties:
      // AddressFamily.InterNetwork - the socket will use the IP version 4 addressing scheme to resolve an address
      // SocketType.Dgram - a socket that supports datagram (message) packets
      // PrototcolType.Udp - the User Datagram Protocol (UDP)
      _socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
      }
    
      /// <summary>
      /// Send the given data to the server using the established connection
      /// </summary>
      /// <param name="serverName">The name of the server</param>
      /// <param name="portNumber">The number of the port over which to send the data</param>
      /// <param name="data">The data to send to the server</param>
      /// <returns>The result of the Send request</returns>
      public string Send(string serverName, int portNumber, string data, bool isBroadcast, out SocketAsyncEventArgs socketEventArg)
      {
      string response = "Operation Timeout";
      // Create SocketAsyncEventArgs context object
    
      // We are re-using the _socket object that was initialized in the Connect method
      if (_socket != null)
      {
          socketEventArg = new SocketAsyncEventArgs();
          // Set properties on context object
    
          System.Diagnostics.Debug.WriteLine("Send(): setting remoteEndPoint");
          if (isBroadcast)
          socketEventArg.RemoteEndPoint = new IPEndPoint(IPAddress.Broadcast, portNumber);
          else
          socketEventArg.RemoteEndPoint = new DnsEndPoint(serverName, portNumber);
          System.Diagnostics.Debug.WriteLine("Send(): remoteEndPoint correctly set");
    
          // Inline event handler for the Completed event.
          // Note: This event handler was implemented inline in order to make this method self-contained.
          socketEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(delegate(object s, SocketAsyncEventArgs e)
          {
          response = e.SocketError.ToString();
          // Unblock the UI thread
          _clientDone.Set();
    
          isHasSent = true; 
          });
    
          // Add the data to be sent into the buffer
          byte[] payload = Encoding.UTF8.GetBytes(data);
          socketEventArg.SetBuffer(payload, 0, payload.Length);
    
          // Sets the state of the event to nonsignaled, causing threads to block
          _clientDone.Reset();
    
          // Make an asynchronous Send request over the socket
          _socket.SendToAsync(socketEventArg);
    
          // Block the UI thread for a maximum of TIMEOUT_MILLISECONDS milliseconds.
          // If no response comes back within this time then proceed
          _clientDone.WaitOne(TIMEOUT_MILLISECONDS);
      }
      else
      {
          socketEventArg = null;
          response = "Socket is not initialized";
      }
    
      return response;
      }
    
      public String UDPReceive(int portNumber, bool isBroadcast)
      {
      SocketAsyncEventArgs socketEventArg;
    
      System.Diagnostics.Debug.WriteLine("calling Send(\"server\", portNumber, \" \", isBroadcast, out socketEventArg)");
      Send("servern", portNumber, " ", !isBroadcast, out socketEventArg);
      Thread.Sleep(1000);
    
      while (!isHasSent)
      {
          Thread.Sleep(1);
      }
      System.Diagnostics.Debug.WriteLine("calling Receive(portNumber, isBroadcast, socketEventArg)");
      return Receive(portNumber, isBroadcast, out socketEventArg);
      } 
    
      /// <summary>
      /// Receive data from the server
      /// </summary>
      /// <param name="portNumber">The port on which to receive data</param>
      /// <returns>The data received from the server</returns>
      public string Receive(int portNumber, bool isBroadcast, out SocketAsyncEventArgs socketEventArg)
      {
      string response = "Operation Timeout";
    
      // We are receiving over an established socket connection
      if (_socket != null)
      {
          // Create SocketAsyncEventArgs context object
          socketEventArg = new SocketAsyncEventArgs();
    
          System.Diagnostics.Debug.WriteLine("Receive(): setting remoteEndPoint");
          if (isBroadcast)
          socketEventArg.RemoteEndPoint = new IPEndPoint(IPAddress.Broadcast, portNumber);
          else 
          socketEventArg.RemoteEndPoint = new IPEndPoint(IPAddress.Any, portNumber);
          System.Diagnostics.Debug.WriteLine("Receive(): remoteEndPoint correctly set");
    
          // Setup the buffer to receive the data
          socketEventArg.SetBuffer(new Byte[MAX_BUFFER_SIZE], 0, MAX_BUFFER_SIZE);
          System.Diagnostics.Debug.WriteLine("Receive(): SetBuffer() correctly called");
    
          // Inline event handler for the Completed event.
          // Note: This even handler was implemented inline in order to make this method self-contained.
          socketEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(delegate(object s, SocketAsyncEventArgs e)
          {
          if (e.SocketError == SocketError.Success)
          {
              System.Diagnostics.Debug.WriteLine("Receive(): SocketError.Success");
              // Retrieve the data from the buffer
              response = Encoding.UTF8.GetString(e.Buffer, e.Offset, e.BytesTransferred);
              response = response.Trim('\0');
          }
          else
          {
              System.Diagnostics.Debug.WriteLine("Receive(): SocketError.Error");
              response = e.SocketError.ToString();
          }
          System.Diagnostics.Debug.WriteLine("Receive(): Set()");
          _clientDone.Set();
          });
    
          System.Diagnostics.Debug.WriteLine("Receive(): Reset()");
          // Sets the state of the event to nonsignaled, causing threads to block
          _clientDone.Reset();
    
          try
          {
          // Make an asynchronous Receive request over the socket
          _socket.ReceiveFromAsync(socketEventArg);
          }
          catch (SocketException sockEx)
          {
          Console.WriteLine(sockEx.Message);
          Console.WriteLine(sockEx.ErrorCode);
          Console.WriteLine(sockEx.StackTrace);
          Console.ReadLine();
          System.Diagnostics.Debug.WriteLine("errorCode=" + errorCode + " " + sockEx.Message + sockEx.ErrorCode + sockEx.StackTrace);
          errorCode = 11;
          response += "errorCode=" + errorCode + " " + sockEx.Message + sockEx.ErrorCode + sockEx.StackTrace;
          }
          catch (Exception ex)
          {
          Console.WriteLine(ex.Message);
          Console.WriteLine(ex.StackTrace);
          Console.ReadLine();
          System.Diagnostics.Debug.WriteLine("errorCode="+errorCode+" "+ex.Message + ex.StackTrace);
          errorCode = 22;
          response += "errorCode="+errorCode+" "+ex.Message + ex.StackTrace;
          }
          // Block the UI thread for a maximum of TIMEOUT_MILLISECONDS milliseconds.
          // If no response comes back within this time then proceed
          System.Diagnostics.Debug.WriteLine("Receive(): _clientDone.WaitOne(TIMEOUT_MILLISECONDS)");
          _clientDone.WaitOne(TIMEOUT_MILLISECONDS);
      }
      else
      {
          socketEventArg = null;
          response = "Socket is not initialized";
      }
      System.Diagnostics.Debug.WriteLine("Receive(): response = " + response);
      return response;
      }
    
      /// <summary>
      /// Closes the Socket connection and releases all associated resources
      /// </summary>
      public void Close()
      {
      if (_socket != null)
      {
          _socket.Close();
      }
      }
    }
    }