How to use advanced socket controls (XAML)
This topic shows how to set advanced socket options on a DatagramSocket, StreamSocket, or StreamSocketListener in a Windows Runtime app.
What you need to know
Technologies
-
Enables network communications using sockets and WebSockets.
Prerequisites
- The following examples in this topic are provided in C# and C++. A basic understanding of sockets is recommended.
Overview of advanced controls
The DatagramSocket, StreamSocket, and StreamSocketListener classes all follow the same model for using advanced controls. Corresponding with each of the above primary classes are related classes to access advanced controls:
- DatagramSocketControl - Provides socket control data on a DatagramSocket object.
- StreamSocketControl - Provides socket control data on a StreamSocket object.
- StreamSocketListenerControl - Provides socket control data on a StreamSocketListener object.
The basic model to use advanced controls is the same for all three classes. The discussion below uses a StreamSocket as an example, but the same process can be used with a DatagramSocket or StreamSocketListener.
- Create a StreamSocket.
- Use the StreamSocket.Control property to get the StreamSocketControl instance associated with a StreamSocket object.
- Get or set a property on the StreamSocketControl to set an advanced socket option.
The app must always set a property on the StreamSocketControl before issuing a connect operation or an operation that will bind the socket. Because of this, it is best to set any advanced options immediately after the socket has been created. Do not try and set a StreamSocketControl property after a socket has called one of the ConnectAsync methods.
Datagram socket controls
The DatagramSocket supports network communication using a UDP datagram socket. The advanced options on the DatagramSocket are limited to a single option:
- DatagramSocketControl.QualityOfService - The quality of service on a DatagramSocket object.
The quality of service affects the thread priority for receiving packets on the DatagramSocket object. The quality of service can be set to one of the two possible values for the SocketQualityOfService enumeration. The Normal setting is the default when a DatagramSocket is created. The LowLatency setting increases thread priority for receiving packets. This option would normally only be used for audio or similar apps that are very timing sensitive.
The following example creates a DatagramSocket and sets the DatagramSocketControl.QualityOfService to LowLatency for a timing-sensitive app. Once this is done, the app can call other methods on the DatagramSocket that bind the socket or connect the socket.
using Windows.Networking.Sockets;
DatagramSocket clientSocket = new DatagramSocket();
// The control object is associated with the socket
// Get the current setting for quality of service
// This isn't needed, but it shows how to get the current setting
SocketQualityOfService currentSetting = clientSocket.Control.QualityOfService;
// Set quality of service to low latency
clientSocket.Control.QualityOfService = LowLatency;
// Now use the DatagramSocket to call:
// BindEndpointAsync, BindServiceNameAsync,
// ConnectAsync, GetOutputstreamAsync, or
// JoinMulticastGroup
using namespace Windows::Networking::Sockets;
DatagramSocket^ clientSocket = ref new DatagramSocket();
// The control object is associated with the socket
// Get the current setting for quality of service
// This isn't needed, but it shows how to get the current setting
SocketQualityOfService currentSetting = clientSocket->Control->QualityOfService;
// Set quality of service to low latency
clientSocket->Control->QualityOfService = LowLatency;
// Now use the DatagramSocket to call:
// BindEndpointAsync, BindServiceNameAsync,
// ConnectAsync, GetOutputstreamAsync, or
// JoinMulticastGroup
StreamSocket socket controls
The StreamSocket supports network communication using a TCP stream socket. There are several advanced options on the StreamSocket:
- StreamSocketControl.KeepAlive - Indicates whether keep-alive packets are sent to the remote destination on a StreamSocket object.
- StreamSocketControl.NoDelay - Indicates whether Nagle's algorithm is used on a StreamSocket object.
- StreamSocketControl.OutboundBufferSizeInBytes - Controls the size, in bytes, of the send buffer to be used for sending data on a StreamSocket object.
- StreamSocketControl.QualityOfService - The quality of service on a StreamSocket object.
In this example, we will change the StreamSocketControl.NoDelay property that controls whether Nagle's algorithm is enabled or disabled.
Nagle's algorithm is a technique to improving the efficiency of TCP/IP networks by reducing the number of packets that are needed to be sent over the network. The algorithm tries to deal with problems caused by an application that repeatedly emits data in small chunks. A TCP packet for IPv4 without any other header options has a 40-byte header (20 bytes for IP and 20 bytes for TCP). So if an app sends only 4 bytes in a packet, the overhead on the packet data is very large. This can occur for a remote access protocol (telnet or secure shell, for example) where most keypresses may generate only a single byte or two of data that is transmitted immediately. Over a slow link, many of these packets may be in transit over the network at the same time. Nagle's algorithm works by combining a number of small outgoing messages, and sending them all at once. When there is a sent packet for which the sender has received no acknowledgment, the sender keeps buffering output until it has a full packet's worth of output. This allows the output to be sent all at once. The impact of applying Nagle's algorithm is to increase the bandwidth at the expense of latency. A well-written app that buffers sends internally should not need to use Nagle's algorithm.
The default setting when a StreamSocket is created is that this option is set to true to disable the Nagle's algorithm. This setting reduces the potential delays when sending small messages. However, if the StreamSocket will be used for an app that sends many small packets and latency is not an issue, then Nagle's algorithm could be enabled to improve efficiency.
The following example creates a StreamSocket and sets the StreamSocketControl.NoDelay to false. Once this is done, the app can call other methods on the StreamSocket that connect the socket.
using Windows.Networking.Sockets;
StreamSocket clientSocket = new Windows.Networking.Sockets.StreamSocket();
// The control object is associated with the socket
// Get the current setting for this option
// This isn't needed, but it shows how to get the current setting
bool currentSetting = clientSocket.Control.NoDelay;
// Don't disable the nagle algorithm
clientSocket.Control.NoDelay = false;
// Now you can use the StreamSocket to call one of the
// ConnectAsync methods
using Windows::Networking::Sockets;
StreamSocket^ clientSocket = ref new StreamSocket();
// The control object is associated with the socket
// Get the current setting for this option
// This isn't needed, but it shows how to get the current setting
bool currentSetting = clientSocket->Control->NoDelay;
// Don't disable the nagle algorithm
clientSocket->Control->NoDelay = false;
// Now you can use the StreamSocket to call one of the
// ConnectAsync methods
StreamSocketListener socket controls
The StreamSocketListener supports listening for an incoming network connection using a TCP stream socket. The advanced options on the StreamSocketListener are limited to a single option:
- StreamSocketListener.QualityOfService - The quality of service to be set on a StreamSocket object created when a connection is received by the StreamSocketListener object.
The quality of service affects the thread priority for receiving packets on the StreamSocket object created when a connection is received by the StreamSocketListener object. The quality of service can be set to one of the two possible values for the SocketQualityOfService enumeration. The Normal setting is the default when a StreamSocket is created when a connection is received. The LowLatency setting increases thread priority for receiving packets on the StreamSocket that is created. This option would normally only be used when accepting connections for audio or similar apps that are very timing sensitive.
The following example creates a StreamSocketListener and sets the StreamSocketListener.QualityOfService to LowLatency for a timing-sensitive app. Once this is done, the app can call other methods on the StreamSocketListener to begin listening for incoming connection requests.
using Windows.Networking.Sockets;
StreamSocketListener listenSocket = new StreamSocketListener();
// The control object is associated with the socket
// Get the current setting for quality of service
// This isn't needed, but it shows how to get the current setting
SocketQualityOfService currentSetting = listenSocket.Control.QualityOfService;
// Set quality of service to low latency
listenSocket.Control.QualityOfService = SocketQualityOfService.LowLatency;
// Now you can use the StreamSocketListener to
// bind to a service name and begin listening for
// incoming connection requests
using namespace Windows::Networking::Sockets;
StreamSocketListener^ listenSocket = ref new StreamSocketListener();
// The control object is associated with the socket
// Get the current setting for quality of service
// This isn't needed, but it shows how to get the current setting
SocketQualityOfService currentSetting = listenSocket->Control->QualityOfService;
// Set quality of service to low latency
listenSocket->Control->QualityOfService = SocketQualityOfService::LowLatency;
// Now you can use the StreamSocketListener to
// bind to a service name and begin listening for
// incoming connection requests
Remarks
In addition to control data, there are a similar set of related classes that provide access to additional socket information on these primary classes:
- DatagramSocketInformation - Provides socket information on a DatagramSocket object.
- StreamSocketInformation - Provides socket information on a StreamSocket object.
- StreamSocketListenerInformation - Provides socket information on a StreamSocketListener object.
The model to access additional socket information follows the same design as the access to control data. The discussion below uses a StreamSocket as an example.
- Create a StreamSocket.
- Use the StreamSocket.Information property to get the StreamSocketInformation instance associated with the StreamSocket object.
- Get a property on the StreamSocketInformation instance to retrieve additional socket information.
There is one significant differences between the socket information and socket control classes. The properties on a StreamSocketControl instance are readable or writable (get or set). In contrast, the properties on a StreamSocketInformation instance are read-only (get). An app may retrieve the value of a property on a StreamSocketControl or StreamSocketInformation instance at any time after the StreamSocket was created. However, an app must always set a property on a StreamSocketControl instance before issuing a connect operation or an operation that will bind the socket.
Related topics
Other
How to connect with a datagram socket
How to connect with a stream socket
How to secure socket connections with TLS/SSL
How to set timeouts on socket operations
Reference