DatagramSocket Multicast functionality on Windows 8.1 throws an error 0x80072AF9 (WSAHOST_NOT_FOUND)

We have noticed multiple customer reports of using the Multicast functionality of the Windows.Networking.Sockets.DatagramSocket class on Windows 8.1.

Most of the reported issues are with sending Multicast packets to the Multicast DNS address of 224.0.0.251 and port 5353, however the same could be true for any multicast address/port.

Multicast DNS (mDNS) provides the ability to perform DNS-like operations on the local link in the absence of any conventional Unicast DNS server. RFC 6762 covers the details of the protocol in further detail and can be found here: http://tools.ietf.org/html/rfc6762 for further reference.

A typical usage pattern of the code that demonstrates this issue is as below.

1. Create a DatagramSocket
2. Call DatagramSocket.BindServiceNameAsync(localServiceName)
3. Call DatagramSocket.JoinMulticastGroup
4. Call DatagramSocket.GetOutputStreamAsync
5. If successful, send data over the stream

Customers have reported that the asynchronous call to GetOutputStreamAsync completes with an error code of 0x80072AF9 = WSAHOST_NOT_FOUND which means: “No such host is known.”

The above logic worked just fine on Windows 8 and it has only been reported with the general availability (GA) of Windows 8.1. If you experience this same problem with Windows 8 system, then there is no workaround on Windows 8 and you can upgrade your system to Windows 8.1. If you continue to see this issue even after upgrading to Windows 8.1, you can use the approach mentioned below. The problem has only been reported for users with systems connected through Wi-Fi rather than being connected through Ethernet.

The problem happens due to an issue in the route selection logic inside the tcpip.sys driver, where a wrong interface (either disabled or an inactive interface) is returned to the caller. When the Multicast packet is sent over that faulty route, the 0x80072AF9 error is returned because there is no active route to that IP Address.

To workaround the issue, you can implement your code logic to select a specific network adapter in Step 2 above, instead of letting the OS choose it for you.

Windows 8.1 has introduced a new overload for the function BindServiceNameAsync(localServiceName, adapter) which you can use to specify a particular network adapter (second parameter).

For example, you can use the NetworkInformation.GetInternetConnectionProfile() function to retrieve the internet connected profile and use the NetworkAdapter of the returned profile in the call to BindServiceNameAsync(localServiceName, adapter) overload of the function. This two parameter overload is new on Windows 8.1 and not available on Windows 8.

Here is a C# version of the implementation which does the same. The DemoProjects.zip at the end of this article contains four zip files, TestMCAppCSharp, TestMCAppVB, TestMCAppCPlusPlus and TestMCAppJS. Each of these contains the projects in C#, VB.Net, C++ and JS language for your reference.

  
 DatagramSocket socket = new DatagramSocket();
 ///...other code...
  
 ///
 /// retrieve the best network adapter to use
 ///
 ConnectionProfile connectionProfile = NetworkInformation.GetInternetConnectionProfile();
  
 ///
 /// call BindServiceNameAsync overload with 2 parameters. This overload is ONLY available on Windows 8.1
 /// Don't specify a local port unless you have some type of dependency on that local port. 
 /// If the local port is being used by some other app, you'll get an exception
 ///
 await socket.BindServiceNameAsync("", connectionProfile.NetworkAdapter); 
  
 socket.JoinMulticastGroup(new HostName(ipAddress));
 IOutputStream outputStream = await socket.GetOutputStreamAsync(new HostName(ipAddress), port);
 ///...other code...

Hopefully this blog will help resolve the above issue for you!

Follow the Windows Store Developer Solutions team on Twitter @wsdevsol. Comments are welcome, both below and on twitter.

DemoProjects.zip