Click here to Skip to main content
15,881,588 members
Articles / Mobile Apps / Windows Phone 7

Peer Communication on Windows Phone 7

Rate me:
Please Sign up or sign in to vote.
5.00/5 (4 votes)
28 Jun 2011CPOL2 min read 29.9K   355   7   4
Peer Communication on Windows Phone 7

Written Against Pre-release Information

One of the new things that we get with Windows Phone 7 is socket support. While I expected to be able to open sockets to other machines with servers running on them, one thing caught me by surprise; that you can also send communication from phone to phone using UDP. I've got to give credit to Ricky_T for pointing out the presence of this feature and posting a code sample. I wanted to try this out myself. So I made a version of the code sample that would run on both Windows Phone and on the desktop (Silverlight 4 in Out of Browser mode). I was pleasantly surprised too that I was able to open up peer communication between the desktop and phone without a problem. This capability provides a number of solutions for other problems that I've been considering, such as automatic discovery and configuration for communicating with services hosted on a user's local network. 

Most of the code used in the desktop and phone version of this example are identical; I've shared some of the same files between projects. From the files that are not shared, the counterparts in the phone and desktop version are still similar. The core of the code is in a class called Peer. Let's take a look at part of the body of that class. 

C#
//Define the port and multicast address to be used for communication
private string _channelAddress = "224.0.0.1";
private int _channelPort = 3007;

//The event to be raised when a message comes in
public event EventHandler<MessageReceivedEventArgs> MessageReceived; 

//the UDP channel over which communication will occur.
private UdpAnySourceMulticastClient _channel;

//Create the channel
public void Initialize()
{
    _channel = new UdpAnySourceMulticastClient(
                      IPAddress.Parse(_channelAddress), _channelPort);
}

//Open the channel and start listening
public void Open()
{
    if (_channel == null)
        Initialize();
    ClientState = ClientStatesEnum.Opening;
            

    _openResult = _channel.BeginJoinGroup((result) =>
                                    {
                                        _channel.EndJoinGroup(result);
                                        ClientState = ClientStatesEnum.Opened;
                                    }, null);   

    Receive();
}
C#
//The receive method is recursive. At the end of a call to receive, it calls itself 
//so that the class can continue listening for incoming requests.
void Receive()
{
    byte[] _receiveBuffer = new byte[1024];

    _channel.BeginReceiveFromGroup(_receiveBuffer, 0, _receiveBuffer.Length, (r) =>
    {
        if(ClientState!=ClientStatesEnum.Closing)
        {
            try
            {
            IPEndPoint source;
            int size= _channel.EndReceiveFromGroup(r, out source);
            OnMessageReceived(_receiveBuffer, size,  source);
            }
            catch (Exception )
            {
            }
            finally
            {
                this.Receive();
            }
        }
    }, null);
}
public void Send(byte[] data)
{
    if(ClientState==ClientStatesEnum.Opened)
    {
        _channel.BeginSendToGroup(data, 0, data.Length, (r) => 
                                  _channel.EndSendToGroup(r),null);
    }
}

This class only sends and receives byte arrays. My only goal here was to see the code work so there are other considerations that I have decided to overlook for now. I made a client to use this code too. The client sends and receives plain text. Before sending a block of text, it is necessary to convert the text to a byte array. The encoding classes in .NET will take care of this for me. When a message comes in, I can also use an encoder to convert the byte array back to a string.

For this program, I am adding the incoming message to a list along with the IP address from which it came:

C#
void _peer_MessageReceived(object sender, MessageReceivedEventArgs e)
{
    Action a = () =>
        {
            string message = System.Text.UTF8Encoding.Unicode.GetString(e.Data, 0, e.Size);
            MessageList.Add(String.Format("{0}:{1}", e.Endpoint.Address.ToString(), message));
            OnIncomingMessageReceived(message, e.Endpoint.Address.ToString());
        };
    if (UIDispatcher == null)
        a();
    else
        UIDispatcher.BeginInvoke(a);
}

public void SendMessage(string message)
{
    byte[] encodedMessage= UTF8Encoding.Unicode.GetBytes(message);
    _peer.Send(encodedMessage);
}

When the code is run on any combination of multiple phones or computers, message types on any one of the devices appears on all of them. Nice! Now to start making use of it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
United States United States
I attended Southern Polytechnic State University and earned a Bachelors of Science in Computer Science and later returned to earn a Masters of Science in Software Engineering. I've largely developed solutions that are based on a mix of Microsoft technologies with open source technologies mixed in. I've got an interest in astronomy and you'll see that interest overflow into some of my code project articles from time to time.



Twitter:@j2inet

Instagram: j2inet


Comments and Discussions

 
Questionunicast using BeginSendTo method Pin
Member 966977527-Mar-13 10:37
Member 966977527-Mar-13 10:37 
GeneralMy vote of 5 Pin
JamesHurst17-Mar-12 0:52
JamesHurst17-Mar-12 0:52 
QuestionNice, but will crash eventually... Pin
Peter Villadsen5-Jul-11 10:42
Peter Villadsen5-Jul-11 10:42 
AnswerNo Stack Overflow Here Pin
Joel Ivory Johnson5-Jul-11 13:29
professionalJoel Ivory Johnson5-Jul-11 13:29 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.