IPAddress from NSData using Bonjour NSNetService in MonoTouch?

bonjour, c#, ios, nsnetservice, xamarin.ios

Solution

The `NSNetService.Addresses` property gives you `NSData` instances which must be converted into something that `IPAddress` (or other .NET types) can digest. E.g.

MemoryStream ms = new MemoryStream ();
(ns.Addresses [0] as NSData).AsStream ().CopyTo (ms);
IPAddress ip = new IPAddress (ms.ToArray ());

Note that this can return you an IPv6 address (or format that `IPAddress` won't accept). You might want to iterate all the `Addresses` to find the best one.

I'll look into adding a convenience method into future versions of Xamarin.iOS.

UPDATE

A more complete version, that returns an `IPAddress`, would look like:

static IPAddress CreateFrom (NSData data)
{
    byte[] address = null;
    using (MemoryStream ms = new MemoryStream ()) {
        data.AsStream ().CopyTo (ms);
        address = ms.ToArray ();
    }
    SocketAddress sa = new SocketAddress (AddressFamily.InterNetwork, address.Length);
    // do not overwrite the AddressFamily we provided
    for (int i = 2; i < address.Length; i++)
        sa [i] = address [i];
    IPEndPoint ep = new IPEndPoint (IPAddress.Any, 0);
    return (ep.Create (sa) as IPEndPoint).Address;
}

Problem

I'm using Xamarin + MonoTouch on iOS to browse for a web server on the network that I can then download files from. The NSNetService that is passed into the resolve event handler contains addresses as NSData. I can't find a good way to turn that NSData into an actual IP address that I can then build a URL from, i.e. http:// < IPAddress > /folder/file.htm This is my NSNetService.AddressResolved event handler: ``` private void OnServiceResolved(object sender, EventArgs args) { NSNetService service = (NSNetService)sender; // service.Port is valid. // service.HostName is valid. // but we want the IP addres, which is in service.Addresses. // None of the following four methods works quite right. IPAddress address = (IPAddress)service.Addresses [0]; // Cannot convert type NSData to IPAddress SocketAddress address2 = (SocketAddress)service.Addresses[0]; // Cannot convert NSData to SocketAddress. A binary copy might work? IPHostEntry entry = (IPHostEntry)service.Addresses [0]; // Cannot convert NSData to IPHostEntry IPHostEntry entry2 = Dns.GetHostByName (service.HostName); // This kinda works, but is dumb. Didn't we just resolve? } ``` What's the right way to get the IP address of the service from an NSNetService in a resolve event?

Original source