Udostępnij za pośrednictwem


Finding Your Own IP Address On Windows Phone Mango

For reasons never adequately explained there is still no API to obtain the IP address of the phone from a WP app. However if you want the IP address on the local wifi network, help is at hand, via this sample code. The way this works is that the phone does a multicast of its own invention, then listens for its own reply. When it arrives the IP address of the sender can be determined, and its yourself! If the phone is not connected to a wifi network then the callback will be passed a null instead of an IPAddress. Please note this requires an OS build of 7704 or later (emulator or phone) as earlier builds are deeply unreliable for multicast.

[Updated on 8/24 to include the actual C# code and also improved how MulticastMessage was calculated so it isnt likely to clash with another phone doing the same thing at the same time]

 using System;
using System.Net;
using System.Net.Sockets;
using System.Diagnostics;
using System.Linq;
using System.Text;
 
namespace FindMyIP
{
    public class MyIPAddress
    {
        Action<IPAddress> FoundCallback;
        UdpAnySourceMulticastClient MulticastSocket;
        const int PortNumber = 50000;       // pick a number, any number
        string MulticastMessage = "FIND-MY-IP-PLEASE" + new Random().Next().ToString();
 
        public void Find(Action<IPAddress> callback)
        {
            FoundCallback = callback;
 
            MulticastSocket = new UdpAnySourceMulticastClient(IPAddress.Parse("239.255.255.250"), PortNumber);
            MulticastSocket.BeginJoinGroup((result) =>
            {
                try
                {
                    MulticastSocket.EndJoinGroup(result);
                    GroupJoined(result);
                }
                catch (Exception ex)
                {
                    Debug.WriteLine("EndjoinGroup exception {0}", ex.Message);
                    // This can happen eg when wifi is off
                    FoundCallback(null);
                }
            },
                null);
        }
 
        void callback_send(IAsyncResult result)
        {
        }
 
        byte[] MulticastData;
        bool keepsearching;
 
        void GroupJoined(IAsyncResult result)
        {
            MulticastData = Encoding.UTF8.GetBytes(MulticastMessage);
            keepsearching = true;
            MulticastSocket.BeginSendToGroup(MulticastData, 0, MulticastData.Length, callback_send, null);
 
            while (keepsearching)
            {
                try
                {
                    byte[] buffer = new byte[MulticastData.Length];
                    MulticastSocket.BeginReceiveFromGroup(buffer, 0, buffer.Length, DoneReceiveFromGroup, buffer);
                }
                catch (Exception ex)
                {
                    Debug.WriteLine("Stopped Group read due to " + ex.Message);
                    keepsearching = false;
                }
            }
        }
 
        void DoneReceiveFromGroup(IAsyncResult result)
        {
            IPEndPoint where;
            int responselength = MulticastSocket.EndReceiveFromGroup(result, out where);
            byte[] buffer = result.AsyncState as byte[];
            if (responselength == MulticastData.Length && buffer.SequenceEqual(MulticastData))
            {
                Debug.WriteLine("FOUND myself at " + where.Address.ToString());
                keepsearching = false;
                FoundCallback(where.Address);
            }
        }
    }
}

Here is a sample button handler to put in a trivial Silverlight test app:

         private void button1_Click(object sender, RoutedEventArgs e)
        {
            MyIPAddress finder = new MyIPAddress();
            finder.Find((address) =>
            {
                Dispatcher.BeginInvoke(() =>
                    {
                        button1.Content = address == null ? "Unknown" : address.ToString();
                    });
            });
        }

Comments

  • Anonymous
    August 11, 2011
    Hey Andy, Been researching for a way to find the IP, thanks for the post.  I'll definitely try this out!

  • Anonymous
    August 12, 2011
    Hey Andy, Just wondering in the callback_send, should there be an EndSendToGroup added to close it off?

  • Anonymous
    August 12, 2011
    Hmm, interesting point Tom, you are probably right about EndSendToGroup although not sure of the side-effects of not doing that. I also realized that the string I send on the multicast should probably have the phone's unique ID in it, so that if two phones on the same network do this they wont find the other by mistake.

  • Anonymous
    August 12, 2011
    Hey Andy, Tried it out at home and it works great.  Thanks for your post again.

  • Anonymous
    November 09, 2011
    Thanks a lot. great job.. I wanted Tip

  • Anonymous
    January 12, 2012
    Hi. It's works with 3G network?

  • Anonymous
    January 13, 2012
    ValeraV: no, as the second sentence says: "on the local wifi network"

  • Anonymous
    January 15, 2012
    thank you

  • Anonymous
    January 17, 2012
    Thank you! Works great. Any way to edit some of this to get the external IP?

  • Anonymous
    January 17, 2012
    andrew_MA: This method stands no chance on an external network as multicast wont work there: instead just hit a web service that returns the IP eg http://whatismyipaddress.com/ (or write your own)

  • Anonymous
    October 31, 2012
    Hey Andy, I tried it on emulator and it is giving me 127.0.0.1 (loop-back IP) is it coz i am using emulator and will work on device?

  • Anonymous
    January 06, 2013
    Doesn't work. Timeout + application exception is thrown from deep inside. (trying to use from the background process).

  • Anonymous
    January 07, 2013
    I am not surprised this wont work in a background process

  • Anonymous
    February 12, 2013
    The comment has been removed

  • Anonymous
    March 07, 2013
    Hello Andy. I'm using your snippet on an application and it just works fine. But when the app is set on background (FAS) or you programmatically call the FindMyIp class, it starts throwing a lot of WebSocket exception (something like 2000 errors in the debugger). I think the cause is that the MulticastSocket is still running in background, but I can't find how to stop it.. Any suggestions? Thanks a lot. If you want to mail me, use panattan@gmail.com Giacomo

  • Anonymous
    March 11, 2013
    Hello, I wrote a comment last week, but it hasn't been published. So the problem is: app throws a lot of "WebSocket" exceptions (something like 2000 catches) when you try to programmatically call this class, or for example, when you put your app in FAS or Tombstoning mode. Any suggestions? Please, I REALLY need your help! Thanks in advice!

  • Anonymous
    September 02, 2013
    @Giacomo @Jack: I quick solved it try catching the DoneReceiveFromGroup and executing the Find (without callback)  in a BackgroundWorker, runAsync executed on "onNavigatedTo" callback of the page, and turned MyIPAddress to MyIPAddress : IDisposable... when you find the ip you call this.Dispose() where it's calling the implemented method Dispose containing if(MulticastSocket != null ) MulticastSocket.Dispose()  so you'r releasing the resources used by the UdpSocketMulticast... Hope this helps Cheers

  • Anonymous
    January 08, 2014
    @Francis: Do you have an example of your amended code as I have followed what you have said in your post but the websocket exceptions still occur Thanks

  • Anonymous
    September 21, 2014
    Is it also possible to get the Phone Name this way?

  • Anonymous
    October 14, 2014
    Antoine: to get the phone name, see my other blog post blogs.msdn.com/.../10465455.aspx