Udostępnij za pośrednictwem


How to set connection preferences for a socket for Windows Phone 8

[ This article is for Windows Phone 8 developers. If you’re developing for Windows 10, see the latest documentation. ]

Windows Phone enables applications to set a preference for the type of network interface to use for network communication. This can be Cellular or NonCellular, meaning a network interface that uses cellular technology or a network interface that does not use cellular technology, respectively. Examples of NonCellular technology are Wi-Fi and Ethernet. If an application’s preference can be satisfied, it is used for network communication. If it cannot be satisfied, network communication takes place using another network interface if available. This topic demonstrates how to set a network interface preference on a socket and then verify the current interface once the socket is connected.

The Microsoft.Phone.Net.NetworkInformation namespace provides extension methods to the Socket class. You can use the SetNetworkPreference(Socket, NetworkSelectionCharacteristics) method to set the preference for a network interface on a socket.

Note

For more information about extension methods, see How to: Call an Extension Method (Visual Basic) or Extension Methods (C# Programming Guide).

Setting Connection Preferences for a Socket

In the following procedure, you put the code in a button click event for testing purposes only. The following procedure assumes that you have a Windows Phone application that has a page with a button named button1.

To set connection preferences for a socket

  1. At the top of the code-behind file for your page, add the following statement.

    using System.Net.Sockets;
    using Microsoft.Phone.Net.NetworkInformation;
    using System.Text;
    
  2. Add the following code to your button click event. This creates a socket and calls the SetNetworkPreference extension method on the socket to set the preferred network interface to use for the socket to be Cellular. A connection is then initiated. While SetNetworkPreference can be called on a socket that is not connected, we attempt a connection here so that the current network interface information can be retrieved. Retrieval of the current network interface on a socket is done using the GetCurrentNetworkInterface(Socket) extension method and is shown in the next step of this procedure.

Important Note:

For this example to work, you must change the serverName and the portNumber in the following code to refer to a service and its port that you can communicate with over this TCP socket. If this is not done, a time-out will be received for the connection request.

Tip

Instead of a server or host name in the DnsEndPoint constructor in the following code, you can use the string representation of an IP address. You can also use an IPEndPoint instead of a DnsEndPoint for the RemoteEndPoint property of the SocketAsyncEventArgs.

``` csharp
        private void button1_Click(object sender, RoutedEventArgs e)
        {

            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            // Set the preferred network interface to be an interface that uses cellular technology. 
            socket.SetNetworkPreference(NetworkSelectionCharacteristics.Cellular);
            

            // To run this application, you should specify the name of a server on your network that is running
            // the required service. Replace the following "Placeholder" text with the name of the server.
            string serverName = "Placeholder";

            // This identifies the port over which to communicate. In this sample, we need to just
            // supply the Echo port number, but you are free to select your own.
            int portNumber = 7;

            // Create DnsEndPoint. 
            DnsEndPoint hostEntry = new DnsEndPoint(serverName, portNumber);

            // Create a SocketAsyncEventArgs object to be used in the connection request.
            SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs();
            socketEventArg.RemoteEndPoint = hostEntry;
            socketEventArg.UserToken = socket;
            socketEventArg.Completed += ShowNetworkInterfaceInformation;

            // // Make an asynchronous Connect request over the socket.
            socket.ConnectAsync(socketEventArg);
        }
```

In the preceding method, we assign the Completed event handler to ShowNetworkInterfaceInformation. This is the callback that is called when the asynchronous socket connection request completes or times out. It is in that method that we get all the network interface information for the socket, if the connection was successful. In this example, we use this information to display what network interface is actually being used by the socket, and this can be compared with the preference set in the preceding code in the call to [SetNetworkPreference](https://msdn.microsoft.com/en-us/library/microsoft.phone.net.networkinformation.socketextensions.setnetworkpreference\(system.net.sockets.socket%2cmicrosoft.phone.net.networkinformation.networkselectioncharacteristics\)\(v=VS.105\)).

Note

If your application requires a specific network interface technology, the extension method SetNetworkRequirement(Socket, NetworkSelectionCharacteristics) can be used to define a required Cellular or NonCellular network interface.

  1. In the same code-behind page, add the following method.

            /// <summary>
            /// Display the network information using the GetCurrentNetworkInterface extension method on the socket.
            /// </summary>
            /// <remarks>This is the callback from the ConnectAsync method.</remarks>
            void ShowNetworkInterfaceInformation(object s, SocketAsyncEventArgs e)
            {
                // When ConnectAsync was called, it was passed the socket object in
                // the UserToken field of the socketEventArg. This context is retrieved once
                // the ConnectAsync has completed.
                Socket socket = e.UserToken as Socket;
    
                // Call GetCurrentNetworkInterface only if the connection was successful.
                if (e.SocketError == SocketError.Success)
                {
                    NetworkInterfaceInfo netInterfaceInfo = socket.GetCurrentNetworkInterface();
    
                    // Use a StringBuilder to efficiently build up an information text about this
                    // NetworkInterfaceInfo.
                    StringBuilder sb = new StringBuilder();
    
                    // For clarity, append a timestamp so that we can see when this information was gathered.
                    sb.AppendLine("Last Updated: " + DateTime.Now.ToString());
    
                    sb.Append("Interface Name: ");
                    sb.AppendLine(netInterfaceInfo.InterfaceName);
    
                    sb.Append("Interface State: ");
                    sb.AppendLine(netInterfaceInfo.InterfaceState.ToString());
    
                    sb.Append("Interface Type: ");
                    sb.AppendLine(netInterfaceInfo.InterfaceType.ToString());
    
                    sb.Append("Interface SubType: ");
                    sb.AppendLine(netInterfaceInfo.InterfaceSubtype.ToString());
    
                    DisplayMessage(sb.ToString(), "Network Interface Information", MessageBoxButton.OK);
                }
                else
                {
                    DisplayMessage(e.SocketError.ToString(), "Error Getting Interface Information", MessageBoxButton.OK);
                }
    
                // Close our socket since we no longer need it. 
                // The scope of this socket instance is this method. It is created every time the method is called. 
                // This was done purely to keep this method as self-contained as possible for this sample. 
                socket.Close();
            }
    

    In the preceding method, the success of the connection request is determined by looking at the SocketError property on the SocketAsyncEventArgs. If the connection was successful, a call is made to the GetCurrentNetworkInterface extension method on the socket object. A simple text output is produced by combining the various property values from the NetworkInterfaceInfo object. Finally, a call is made to DisplayMessage, which is described in the following code.

  2. In the same code-behind page, add the following method.

            /// <summary>
            /// This helper method ensures that MessageBox.Show() is called on the UI thread.
            /// </summary>
            void DisplayMessage(string text, string caption, MessageBoxButton buttonConfiguration)
            {
                Dispatcher.BeginInvoke(() =>
                {
                    MessageBox.Show(text, caption, buttonConfiguration);
                });
            }
    
  3. After you build and run your solution, you should see a MessageBox like the following.

Note

In the preceding image, the value of Interface SubType is Unknown. However, when connected to a cellular network, instead of being tethered or connected over Wi-Fi, this field displays the cellular network type, such as 2G and 3G.

See Also

Reference

System.Net.Sockets

Microsoft.Phone.Net.NetworkInformation

NetworkSelectionCharacteristics

Other Resources

Sockets for Windows Phone 8

Network and network interface information for Windows Phone 8

How to set connection requirements for a socket for Windows Phone 8