Click here to Skip to main content
Click here to Skip to main content

Peer Communication on Windows Phone 7

, 28 Jun 2011
Rate this:
Please Sign up or sign in to vote.
Download Code (101 KB)Written against pre-release informationOne 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 surprised; that you can also send communication fro

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 to 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. 

//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 tje cjamme;
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();
}
//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:

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)

About the Author

Joel Ivory Johnson
Software Developer Razorfish
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.
 
For the past few years I've been providing solutions to clients using Microsoft technologies for web and Windows applications.
 
While most of my CodeProject.com articles are centered around Windows Phone it is only one of the areas in which I work and one of my interests. I also have interest in mobile development on Android and iPhone. Professionally I work with several Microsoft technologies including SQL Server technologies, Silverlight/WPF, ASP.Net and others. My recreational development interest are centered around Artificial Inteligence especially in the area of machine vision.
 
Follow on   Twitter

Comments and Discussions

 
Questionunicast using BeginSendTo method PinmemberMember 966977527-Mar-13 10:37 
GeneralMy vote of 5 PinmemberJamesWittHurst17-Mar-12 0:52 
QuestionNice, but will crash eventually... PinmemberPeter Villadsen5-Jul-11 10:42 
AnswerNo Stack Overflow Here PinmemberJoel Ivory Johnson5-Jul-11 13:29 

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

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

| Advertise | Privacy | Mobile
Web03 | 2.8.140709.1 | Last Updated 28 Jun 2011
Article Copyright 2011 by Joel Ivory Johnson
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid