在Windows Phone 8 UDP组播组 [英] UDP multicast group on Windows Phone 8

查看:149
本文介绍了在Windows Phone 8 UDP组播组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好了,这是一个我一直在努力,现在弄清楚了几天。我们在Windows Phone 7的应用,其中手机加入组播组,然后发送和接收邮件的组互相交谈。注 - 这是电话到电话通信



现在我想端口这个应用程序到Windows Phone 8 - 使用Visual Studio中的转换为Phone 8的功能2012 - 到目前为止好。直到我尝试将手机进行测试,以电话通讯。该手机似乎加入小组罚款,它们发送的数据包确定。他们甚至接受他们发送给该组的消息 - 但是,没有手机曾经收到另一个手机的消息



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

  //构造
公众的MainPage()
{
的InitializeComponent();
}

//该组播组地址加入。
//必须是从224.0.0.0到239.255.255.255
私人常量字符串GROUP_ADDRESS =224.0.1.1的范围;

//在其上进行通信,组播组
私人const int的GROUP_PORT = 55562端口;

//从任何来源
UdpAnySourceMulticastClient _client = NULL的多播流量的客户端接收器;

//缓冲区传入数据
私人字节[] _receiveBuffer;

//在这个通信
私人const int的MAX_MESSAGE_SIZE = 512的消息的最大大小;

私人无效PhoneApplicationPage_Loaded(对象发件人,RoutedEventArgs E)
{
_client =新UdpAnySourceMulticastClient(IPAddress.Parse(GROUP_ADDRESS),GROUP_PORT);
_receiveBuffer =新的字节[MAX_MESSAGE_SIZE]

_client.BeginJoinGroup(
结果=>
{
_client.EndJoinGroup(结果);
_client.MulticastLoopback = TRUE;
接收();
},NULL);
}

私人无效sendRequest将(字符串s)
{
如果(string.IsNullOrWhiteSpace(S))回报;

字节[] =的RequestData Encoding.UTF8.GetBytes(S);

_client.BeginSendToGroup(的RequestData,0,requestData.Length,
结果=>
{
_client.EndSendToGroup(结果);
接收( );
},NULL);
}

私人无效接收()
{
Array.Clear(_receiveBuffer,0,_receiveBuffer.Length);
_client.BeginReceiveFromGroup(_receiveBuffer,0,_receiveBuffer.Length,
结果=>
{
IPEndPoint源;

_client.EndReceiveFromGroup(结果,出源);

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

字符串消息=的String.Format([{0} ]:{1},source.Address.ToString(),dataReceived);
日志(消息,FALSE);

接收();
},NULL);
}

私人无效日志(字符串消息,布尔isOutgoing)
{
如果(string.IsNullOrWhiteSpace(message.Trim('\0')))
{
的回报;
}

//始终确保这样做的UI线程。
Deployment.Current.Dispatcher.BeginInvoke(
()=>
{
线方向=(isOutgoing)>>中:<< ;
串时间戳= DateTime.Now.ToString(HH:MM:SS);
=信息+时间戳+方向信息;
lbLog.Items.Add(消息);

//确保我们增加了产品对用户可见
lbLog.ScrollIntoView(消息);
});

}

私人无效btnSend_Click(对象发件人,RoutedEventArgs E)
{
//不要发送空消息。
如果
{
//Send(txtInput.Text)(String.IsNullOrWhiteSpace(txtInput.Text)!);
sendRequest将(txtInput.Text);
}
}

私人无效btnStart_Click(对象发件人,RoutedEventArgs E)
{
sendRequest将(从现在做起);
}

为了简单地测试出UDP协议栈,我下载从MSDN样本发现这里和我测试的一对Windows Phone 7的设备和它的作品为预期。然后我转换到Windows电话8和部署到我的手机,再次设备似乎启动其连接,并且用户可以输入他们的名字。然而,再设备将无法看到或与其他设备进行通信。



最后我实现了使用新的DatagramSocket实现一个简单的通信测试,我再次看到成功启动, 。但没有设备间通信



这是一个使用数据报套接字实现页面背后的同一代码:

  //构造
公众的MainPage()
{
的InitializeComponent();
}

//该组播组地址加入。
//必须是从224.0.0.0到239.255.255.255
私人常量字符串GROUP_ADDRESS =224.0.1.1的范围;

//在其上进行通信,组播组
私人const int的GROUP_PORT = 55562端口;

私人DatagramSocket的插座= NULL;

私人无效日志(字符串消息,布尔isOutgoing)
{
如果(string.IsNullOrWhiteSpace(message.Trim('\0')))
返回;

//始终确保这样做的UI线程。
Deployment.Current.Dispatcher.BeginInvoke(
()=>
{
线方向=(isOutgoing)>>中:<< ;
串时间戳= DateTime.Now.ToString(HH:MM:SS);
=信息+时间戳+方向信息;
lbLog.Items.Add(消息);

//确保我们增加了产品对用户可见
lbLog.ScrollIntoView(消息);
});
}

私人无效btnSend_Click(对象发件人,RoutedEventArgs E)
{
//不要发送空消息。
如果
{
//Send(txtInput.Text)(String.IsNullOrWhiteSpace(txtInput.Text)!);
SendSocketRequest(txtInput.Text);
}
}

私人无效PhoneApplicationPage_Loaded(对象发件人,RoutedEventArgs E)
{
插座=新的DatagramSocket();
socket.MessageReceived + = socket_MessageReceived;


{
//连接到服务器(在我们的例子中,我们在上一步中创建的监听器)。
等待socket.BindServiceNameAsync(GROUP_PORT.ToString());
socket.JoinMulticastGroup(新Windows.Networking.HostName(GROUP_ADDRESS));
System.Diagnostics.Debug.WriteLine(socket.ToString());
}
赶上(例外的例外)
{
扔;
}
}

私人异步无效SendSocketRequest(字符串消息)
{
//创建一个DataWriter如果我们不创建一个呢。否则,使用一个已经缓存。
// DataWriter作家;
VAR流=等待socket.GetOutputStreamAsync(新Windows.Networking.HostName(GROUP_ADDRESS),GROUP_PORT.ToString());
//作家=新DataWriter(socket.OutputStream);
DataWriter作家=新DataWriter(流);

//第一次写的字符串作为UINT32值的长度由字符串跟进。写数据到笔者只是数据存储在内存中。
// stream.WriteAsync(
writer.WriteString(消息);

//本地缓冲的数据写入到网络

{。
等待writer.StoreAsync();
日志(消息,真);
System.Diagnostics.Debug.WriteLine(socket.ToString());
}
赶上(例外的例外)
{
抛出;
}
终于
{
writer.Dispose();
}
}

无效socket_MessageReceived(DatagramSocket的发件人,DatagramSocketMessageReceivedEventArgs参数)
{

{
UINT stringLength = args.GetDataReader()UnconsumedBufferLength;
弦乐味精= args.GetDataReader()ReadString(stringLength);

日志(味精,假);
}
赶上(例外的例外)
{
抛出;
}
}

昨天晚上,我拿了手机在家测试他们我家的无线网络上,低看哪我得到成功的设备通信。



因此​​,要回顾一下 - 我的遗产Windows Phone 7的代码运行我的工作,网络上的罚款。端口到Windows Phone 8(没有实际的代码更改)不会发送设备间通信。此代码我的家庭网络上工作。该代码附加了调试运行,并有执行过程中的任何地方没有错误或异常的迹象



我使用的手机是:



Windows Phone 7的 - 诺基亚Lumia 900(* 2),诺基亚Lumia 800(* 3)
的Windows Phone 8 - 诺基亚Lumia 920(* 1),诺基亚Limia 820(* 2)



这些都是运行最新的操作系统,并在开发人员模式。
开发环境是Windows 8企业运行Visual Studio 2012专业版



我不能告诉你很多关于工作的无线网络 - 除了Phone 7设备有任何麻烦。



对于家庭无线网络我用,这只是一个基本的BT宽带路由器没有任何的改变了'开箱即用'的设置。



显然有一个与这两个网络的配置方式的问题,但也有很清楚的Windows Phone 8的实现UDP消息的方式的问题。



任何投入,将不胜感激,因为这是推动我疯了现在。


解决方案

UDP多播工作得出奇。根据我的经验的Windows Phone 7,所以你应该结帐的Windows Phone 8相同



下面是我的经验:




  1. 检查什么的正式支持,比如下的Windows Phone OS 7.1(去年OS我切换之前试过),TCP单播,UDP单播和UDP多播客户端的支持。

  2. Windows phone的许可证某些版本的接收UDP会话只有当客户端第一次打开它,并在会话不超过10秒内收到,这似乎是某种安全的事情在Windows Phone上。

  3. 地址不同的尝试:在范围内的组播地址224.0.0.0从到224.0.0.255包容性的知名保留的多播地址

  4. 检查。无论是在虚拟机和在一个真正的电话设备,该行为可以不同。


  5. OK this is one I've been trying to figure out for a few days now. We have an application on Windows Phone 7 where phones join a multicast group and then send and receive messages to the group to talk to each other. Note - this is phone to phone communication.

    Now I'm trying to port this application to Windows Phone 8 - using the 'Convert to Phone 8' feature in Visual Studio 2012 - so far so good. Until I try to test the phone to phone communication. The handsets seem to join the group fine, and they send the datagrams OK. They even receive the messages that they send to the group - however, no handset ever receives a message from another handset.

    Here is the sample code behind to my page:

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

    In order to simply test out the UDP stack, I downloaded the sample from MSDN found here and I tested this on a pair of Windows Phone 7 devices and it works as expected. Then I converted to Windows Phone 8 and deployed to my handsets, again the devices seem to initiate their connection, and the user can enter their name. However, again the devices can't see or communicate with other devices.

    Finally I implemented a simple communication test using the new DatagramSocket implementation, and again I see successful initiation, but no inter-device communication.

    This is the same code behind page using the datagram socket implementation:

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

    Last night I took the handsets home to test them on my home wireless network, low and behold I get successful device communication.

    So to recap - my legacy Windows Phone 7 code runs fine on my work network. The port to Windows Phone 8 (no actual code change) does not send inter-device communication. This code does work on my home network. The code runs with the debugger attached and there are no signs of errors or exceptions anywhere during execution.

    The handsets I'm using are:

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

    These are all running the latest OS, and are in developer mode. Development environment is Windows 8 Enterprise running Visual Studio 2012 Professional

    I cant tell you much about the work wireless network - other than the Phone 7 devices have no trouble.

    As for the home wireless network i used, that's just a basic BT Broadband router with none of the 'out the box' settings altered.

    Clearly there is an issue with the way that the two network are configured, but there is also very clearly an issue with the way Windows Phone 8 implements UDP messages.

    Any input would be appreciated as this is driving me mad right now.

    解决方案

    UDP multicast works pretty strangely under windows phone 7 from my experience so you should checkout the same for windows phone 8.

    Here is my experience:

    1. check what is officially supported, for instance under Windows Phone OS 7.1 (last OS I tried before switching), TCP unicast, UDP unicast, and UDP multicast clients are supported.
    2. some versions of Windows phone permit to receive a UDP session only if the client first opened it and the session is received within no more than 10 seconds, this seems like some sort of security thing on Windows Phone.
    3. try with different addresses: multicast addresses in the range from 224.0.0.0 to 224.0.0.255 inclusive are "well-known" reserved multicast addresses.
    4. Check both in the virtual machine and in a real phone device, the behaviour may differ.

    这篇关于在Windows Phone 8 UDP组播组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆