Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Windows Phone 8上的UDP多播组_C#_Sockets_Udp_Windows Phone 8_Datagram - Fatal编程技术网

C# Windows Phone 8上的UDP多播组

C# Windows Phone 8上的UDP多播组,c#,sockets,udp,windows-phone-8,datagram,C#,Sockets,Udp,Windows Phone 8,Datagram,好的,这是我几天来一直想弄清楚的。我们在WindowsPhone7上有一个应用程序,其中手机加入一个多播组,然后向该组发送和接收消息,以便彼此通话。注意-这是电话对电话的通信 现在,我正在尝试将此应用程序移植到Windows Phone 8—使用Visual Studio 2012中的“转换为Phone 8”功能—到目前为止效果良好。直到我尝试测试电话对电话的通信。手机似乎很好地加入了这个群体,而且它们发送的数据报也很正常。他们甚至会收到发送给群组的信息——然而,没有一部手机会收到来自另一部手机

好的,这是我几天来一直想弄清楚的。我们在WindowsPhone7上有一个应用程序,其中手机加入一个多播组,然后向该组发送和接收消息,以便彼此通话。注意-这是电话对电话的通信

现在,我正在尝试将此应用程序移植到Windows Phone 8—使用Visual Studio 2012中的“转换为Phone 8”功能—到目前为止效果良好。直到我尝试测试电话对电话的通信。手机似乎很好地加入了这个群体,而且它们发送的数据报也很正常。他们甚至会收到发送给群组的信息——然而,没有一部手机会收到来自另一部手机的信息

以下是我的页面后面的示例代码:

// 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");
}
//构造函数
公共主页()
{
初始化组件();
}
//要加入的多播组的地址。
//必须在224.0.0.0到239.255.255.255之间
private const string GROUP_ADDRESS=“224.0.1.1”;
//要通过其与多播组通信的端口
私有const int GROUP_PORT=55562;
//来自任何源的多播通信的客户端接收器
UdpAnySourceMulticastClient _client=null;
//传入数据的缓冲区
专用字节[]\u接收缓冲区;
//此通信中消息的最大大小
private const int MAX_MESSAGE_SIZE=512;
已加载专用void PhoneApplicationPage_(对象发送方,路由目标)
{
_client=new-UdpAnySourceMulticastClient(IPAddress.Parse(GROUP\u地址),GROUP\u端口);
_receiveBuffer=新字节[最大消息大小];
_client.beginjoin组(
结果=>
{
_client.EndJoinGroup(结果);
_client.MulticastLoopback=true;
接收();
},空);
}
私有void SendRequest(字符串s)
{
if(string.IsNullOrWhiteSpace)返回;
byte[]requestData=Encoding.UTF8.GetBytes;
_client.BeginSendToGroup(requestData,0,requestData.Length,
结果=>
{
_client.EndSendToGroup(结果);
接收();
},空);
}
私有无效接收()
{
Array.Clear(_receiveBuffer,0,_receiveBuffer.Length);
_client.BeginReceiveFromGroup(_-receiveBuffer,0,_-receiveBuffer.Length,
结果=>
{
点源;
_client.EndReceiveFromGroup(结果,来源外);
stringdatareceived=Encoding.UTF8.GetString(_-receiveBuffer,0,_-receiveBuffer.Length);
string message=string.Format(“[{0}]:{1}”,source.Address.ToString(),dataReceived);
日志(消息,错误);
接收();
},空);
}
私有无效日志(字符串消息,bool ISOUTTING)
{
if(string.IsNullOrWhiteSpace(message.Trim('\0'))
{
返回;
}
//始终确保在UI线程上执行此操作。
部署.Current.Dispatcher.BeginInvoke(
() =>
{

字符串方向=(正在输出)?“>>”:“>”:"我注意到您使用了环回。我认为这意味着当您从客户端发送消息时,您也将收到您发送的消息。这意味着您的接收处理程序将启动。它的效果是以一种似乎不线程安全的方式清除接收缓冲区。尝试在接收方法中放置一些Try-catch,看看是否有任何异常正在发生,但您可能在任何情况下都不使用共享接收缓冲区。

您是否尝试加入其他多播组?因为224.0.1.1在IANA分配时似乎正在使用。您可以找到所有的


可能在Windows Phone 8上,某些服务会更严格地侦听传入的消息(例如,在内核模式下运行的网络服务),并且这些消息永远不会转发给您。

根据我的经验,UDP多播在Windows Phone 7下的工作非常奇怪,因此您应该在Windows Phone 8上签出相同的功能

以下是我的经验:

  • 检查官方支持的内容,例如在Windows Phone OS 7.1(切换前我尝试的最后一个操作系统)下,支持TCP单播、UDP单播和UDP多播客户端
  • 某些版本的Windows phone只允许在客户端首次打开UDP会话并在不超过10秒内接收到该会话时才允许接收UDP会话,这似乎是Windows phone上的某种安全措施
  • 尝试使用不同的地址:224.0.0.0到224.0.0.255(含)范围内的多播地址是“众所周知的”保留多播地址
  • 在虚拟机和真实的电话设备中进行检查,行为可能会有所不同

  • 我从微软得到的最新评论是,这可能与堆栈中的错误有关。目前我正在等待他们的回复。当我听到更多信息时,我将更新此帖子。但是,如果SendSocketRequest实现的第一行更改为:
    var stream=waitis,WinRT实现可以正常工作ocket.GetOutputStreamAsync(新的Windows.Networking.HostName(IPAddress.Broadcast.ToString()),GROUP_PORT.ToString());
    尝试使用不同的组地址,如“239.0.0.11”.还有微软的消息吗?我遇到了同样的问题,还没有找到解决办法。我也遇到了同样的问题。你有什么新消息吗???@nucleons自从微软确认漏洞在他们的堆栈中后,我没有听到任何其他的消息。我们正在使用我上面描述的解决办法;自从它起作用后,我们已经转移到我们的new工作项。如果我从微软那里听到任何关于此问题解决方案的消息,我会更新此帖子。
    // 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;
        }
    }