Conceptos básicos de redesNetworking basics

Cosas que debes hacer para cualquier aplicación habilitada para la redThings you must do for any network-enabled app.

FuncionalidadesCapabilities

Para usar la funciones de red, debes agregar elementos de la funcionalidad apropiada al manifiesto de la aplicación.In order to use networking, you must add appropriate capability elements to your app manifest. Si no se especifica ninguna funcionalidad de red en el manifiesto de la aplicación, la aplicación no tendrá ninguna funcionalidad de red y se producirá un error de cualquier intento de conexión a la red.If no network capability is specified in your app's manifest, your app will have no networking capability, and any attempt to connect to the network will fail.

Definamos las funcionalidades de red más usadas:The following are the most-used networking capabilities.

CapacidadCapability DescripciónDescription
internetClientinternetClient Proporciona acceso saliente a Internet y a redes de lugares públicos, como aeropuertos y cafeterías.Provides outbound access to the Internet and networks in public places, like airports and coffee shop. La mayoría de las aplicaciones que requieren acceso a Internet deben usar esta funcionalidad.Most apps that require Internet access should use this capability.
internetClientServerinternetClientServer Proporciona a la aplicación acceso entrante y saliente a Internet de redes en lugares públicos, como aeropuertos y cafeterías.Gives the app inbound and outbound network access from the Internet and networks in public places like airports and coffee shops.
privateNetworkClientServerprivateNetworkClientServer Otorga a la aplicación acceso entrante y saliente a la Red en lugares de confianza del usuario, como su hogar o el trabajo.Gives the app inbound and outbound network access at the user's trusted places, like home and work.

En determinadas circunstancias, existen otras funcionalidades que pueden ser necesarias para la aplicación.There are other capabilities that might be necessary for your app, in certain circumstances.

CapacidadCapability DescripciónDescription
enterpriseAuthenticationenterpriseAuthentication Permite que una aplicación se conecte a los recursos de red que precisan credenciales de dominio.Allows an app to connect to network resources that require domain credentials. Por ejemplo, una aplicación que recupera datos de servidores SharePoint en una Intranet privada.For example, an app that retrieves data from SharePoint servers on a private Intranet. Con esta funcionalidad puedes usar tus credenciales para acceder a recursos de la red en una red que exija credenciales.With this capability your credentials can be used to access network resources on a network that requires credentials. Una aplicación con esta funcionalidad puede suplantarte en la red.An app with this capability can impersonate you on the network. No necesitas esta funcionalidad para que la aplicación pueda obtener acceso a Internet a través de un proxy de autenticación.You don't need this capability in order to allow your app to access the Internet via an authenticating proxy.

Para obtener más información, consulta la documentación para el escenario de la funcionalidad de Enterprise en Funcionalidades restringidas.For more details, see the documentation for the Enterprise capability scenario in Restricted capabilities.
proximityproximity Es necesaria para la comunicación de datos en proximidad con dispositivos que se encuentran cerca del equipo.Required for near-field proximity communication with devices in close proximity to the computer. La comunicación de datos en proximidad puede usarse para realizar envíos o para conectar con una aplicación de un dispositivo cercano.Near-field proximity may be used to send or connect with an application on a nearby device.

Esta funcionalidad permite que la aplicación acceda a la red para conectarse a un dispositivo en proximidad, con el consentimiento del usuario para enviar una invitación o aceptarla.This capability allows an app to access the network to connect to a device in close proximity, with user consent to send an invite or accept an invite.
sharedUserCertificatessharedUserCertificates Esta funcionalidad permite que la aplicación obtenga acceso a los certificados de software y hardware como, por ejemplo, los certificados de una tarjeta inteligente.This capability allows an app to access software and hardware certificates, such as smart card certificates. Cuando se invoca esta funcionalidad en tiempo de ejecución, el usuario debe realizar ciertas acciones, como insertar una tarjeta o seleccionar un certificado.When this capability is invoked at runtime, the user must take action, such as inserting a card or selecting a certificate.

Con esta funcionalidad, se usan los certificados de software y hardware o una tarjeta inteligente para la identificación en la aplicación.With this capability, your software and hardware certificates or a smart card are used for identification in the app. Esta funcionalidad la pueden usar para la identificación el empleador, el banco o los servicios gubernamentales.This capability may be used by your employer, bank, or government services for identification.

Comunicación cuando la aplicación no está en primer planoCommunicating when your app is not in the foreground

El artículo Support your app with background tasks (Consigue que tu aplicación sea compatible con tareas en segundo plano) contiene información general sobre el uso de tareas en segundo plano para que realicen trabajos cuando la aplicación no esté en primer plano.Support your app with background tasks contains general information about using background tasks to do work when your app is not in the foreground. Más concretamente, tu código debe realizar unos pasos especiales para recibir notificaciones cuando no es la aplicación en primer plano actual y llegan datos a través de la red para esta.More specifically, your code must take special steps to be notified when it is not the current foreground app and data arrives over the network for it. Usaste desencadenadores de canal de control para este propósito en Windows 8 y aún se admiten en Windows 10.You used Control Channel Triggers for this purpose in Windows 8, and they are still supported in Windows 10. Encontrarás información completa acerca del uso de desencadenadores de canal de control aquí.Full information about using Control Channel Triggers is available here. Esta nueva tecnología de Windows 10 proporciona una mejor funcionalidad con menos sobrecarga en algunos escenarios, como los siguientes sockets de secuencia habilitados para la inserción: el agente de sockets y los desencadenadores de actividad de socket.A new technology in Windows 10 provides better functionality with lower overhead for some scenarios, such as push-enabled stream sockets: the socket broker and socket activity triggers.

Si la aplicación usa DatagramSocket, StreamSocket o StreamSocketListener, podrá transferir la propiedad de un socket abierto a un agente de sockets proporcionado por el sistema y, a continuación, salir del primer plano o incluso cerrarse.If your app uses DatagramSocket, StreamSocket, or StreamSocketListener, then your app can transfer ownership of an open socket to a socket broker provided by the system, and then leave the foreground, or even terminate. Cuando se establece una conexión en el socket transferido o si llega tráfico a ese socket, se activa la aplicación o su tarea en segundo plano designada.When a connection is made on the transferred socket, or traffic arrives on that socket, then your app or its designated background task are activated. Si la aplicación no se está ejecutando, se iniciará.If your app is not running, it is started. A continuación, el agente de sockets notifica a la aplicación mediante la clase SocketActivityTrigger, que hay tráfico nuevo.The socket broker then notifies your app using a SocketActivityTrigger that new traffic has arrived. Es entonces cuando la aplicación recupera el socket desde el agente de sockets y procesa el tráfico en el mismo socket.Your app reclaims the socket from the socket broker and process the traffic on the socket. Esto significa que la aplicación consume menos recursos del sistema cuando no se está procesando activamente el tráfico de red.This means that your app consumes far less system resources when it is not actively processing network traffic.

El agente de socket está pensado para reemplazar los desencadenadores de canal de control cuando sea aplicable, ya que proporciona la misma funcionalidad, pero con menos restricciones y una menor superficie de memoria.The socket broker is intended to replace Control Channel Triggers where it is applicable, because it provides the same functionality, but with fewer restrictions and a smaller memory footprint. El agente de socket puede usarse en aplicaciones que no son aplicaciones con pantalla de bloqueo y se usa la misma manera en los teléfonos como en otros dispositivos.Socket broker can be used by apps that are not lock screen apps, and it is used the same way on phones as on other devices. Las aplicaciones no necesitan estar ejecutándose cuando llegue el tráfico para que sean activadas por el agente de socket.Apps need not be running when traffic arrives in order to be activated by the socket broker. Además, el agente de socket admite la capacidad de escuchar en los sockets TCP, que no son compatibles con los desencadenadores de canal de control.And the socket broker supports listening on TCP sockets, which Control Channel Triggers do not support.

Elección de un desencadenador de redChoosing a network trigger

Hay algunos escenarios donde cualquier tipo de desencadenador sería adecuado.There are some scenarios where either kind of trigger would be suitable. Cuando elijas qué tipo de desencadenador usar en tu aplicación, ten en cuenta lo siguiente.When you are choosing which kind of trigger to use in your app, consider the following advice.

Para ver detalles y ejemplos acerca de cómo usar el agente de sockets, consulta Comunicaciones de red en segundo plano.For details and examples of how to use the socket broker, see Network communications in the background.

Conexiones segurasSecured connections

Los protocolos Capa de sockets seguros (SSL) y Seguridad de la capa de transporte (TLS) son protocolos criptográficos diseñados para proporcionar autenticación y cifrado para comunicaciones de red.Secure Sockets Layer (SSL) and the more recent Transport Layer Security (TLS) are cryptographic protocols designed to provide authentication and encryption for network communication. Estos protocolos están diseñados para evitar interceptaciones y alteraciones cuando se envían y reciben datos de red.These protocols are designed to prevent eavesdropping and tampering when sending and receiving network data. Usan un modelo de cliente-servidor para los intercambios de protocolos.These protocols use a client-server model for the protocol exchanges. También usan certificados digitales y entidades de certificación para comprobar que el servidor sea realmente el que dice ser.These protocols also use digital certificates and certificate authorities to verify that the server is who it claims to be.

Crear conexiones de sockets segurasCreating secure socket connections

Un objeto StreamSocket se puede configurar para usar SSL/TLS en comunicaciones entre el cliente y el servidor.A StreamSocket object can be configured to use SSL/TLS for communications between the client and the server. Esta compatibilidad con SSL/TLS se limita al uso del objeto StreamSocket como cliente en la negociación de SSL/TLS.This support for SSL/TLS is limited to using the StreamSocket object as the client in the SSL/TLS negotiation. No se puede usar SSL/TLS con el objeto StreamSocket que haya creado la clase StreamSocketListener cuando se reciben comunicaciones entrantes, porque la clase StreamSocket no implementa la negociación de SSL/TLS como servidor.You cannot use SSL/TLS with the StreamSocket created by a StreamSocketListener when incoming communications are received, because SSL/TLS negotiation as a server is not implemented by the StreamSocket class.

Hay dos formas de asegurar una conexión de StreamSocket con SSL/TLS:There are two ways to secure a StreamSocket connection with SSL/TLS:

  • ConnectAsync: establece la conexión inicial a un servicio de red y negocia inmediatamente el uso de SSL/TLS de todas las comunicaciones.ConnectAsync - Make the initial connection to a network service and negotiate immediately to use SSL/TLS for all communications.
  • UpgradeToSslAsync: conecta inicialmente con un servicio de red sin cifrado.UpgradeToSslAsync - Connect initially to a network service without encryption. La aplicación puede enviar o recibir datos.The app may send or receive data. A continuación, actualiza la conexión para usar SSL/TLS en todas las comunicaciones.Then, upgrade the connection to use SSL/TLS for all further communications.

El SocketProtectionLevel especifica el nivel de protección de socket deseado con el que la aplicación quiere establecer o actualizar la conexión.The SocketProtectionLevel specifies the desired socket protection level the app wants to establish or upgrade the connection with. Sin embargo, el nivel de protección definitivo de la conexión establecida se determina en un proceso de negociación entre ambos puntos de la conexión.However, the eventual protection level of the established connection is determined in a negotiation process between both endpoints of the connection. El resultado puede ser un nivel de protección inferior que el especificado, si el otro punto de conexión solicita un nivel inferior.The result can be a lower protection level than the one you specified, if the other endpoint requests a lower level.

Una vez finalizada correctamente la operación asincrónica, puedes recuperar el nivel de protección solicitado que se usó en la llamada ConnectAsync o UpgradeToSslAsync a través de la propiedad StreamSocketinformation.ProtectionLevel.After the async operation has completed successfully, you can retrieve the requested protection level used in the ConnectAsync or UpgradeToSslAsync call through the StreamSocketinformation.ProtectionLevel property. Sin embargo, esto no refleja el nivel de protección real que la conexión está usando.However, this does not reflect the actual protection level the connection is using.

Nota

El código no debe depender implícitamente del uso de un nivel de protección concreto, ni de la suposición de que se usa un nivel de seguridad específico de manera predeterminada.Your code should not implicitly depend on using a particular protection level, or on the assumption that a given security level is used by default. El panorama de seguridad cambia constantemente, y los protocolos y niveles de protección predeterminados cambian con el tiempo para evitar el uso de protocolos con puntos débiles conocidos.The security landscape changes constantly, and protocols and default protection levels change over time in order to avoid the use of protocols with known weaknesses. Los valores predeterminados pueden variar según la configuración del equipo individual o según el software instalado y las revisiones aplicadas.Defaults can vary depending on individual machine configuration, or on which software is installed and which patches have been applied. Si la aplicación depende del uso de un nivel de seguridad concreto, debes especificar explícitamente ese nivel y, a continuación, comprobar que realmente se usa en la conexión establecida.If your app depends on the use of a particular security level, then you must explicitly specify that level and then check to be sure that it is actually in use on the established connection.

Usar ConnectAsyncUse ConnectAsync

ConnectAsync se puede usar para establecer la conexión inicial a un servicio de red y, a continuación, negociar inmediatamente el uso de SSL/TLS de todas las comunicaciones.ConnectAsync can be used to establish the initial connection with a network service and then negotiate immediately to use SSL/TLS for all communications. Hay dos métodos ConnectAsync que admiten pasar un parámetro protectionLevel:There are two ConnectAsync methods that support passing a protectionLevel parameter:

Si el parámetro protectionLevel se establece en Windows.Networking.Sockets.SocketProtectionLevel.Ssl cuando se llama a cualquiera de los métodos ConnectAsync arriba mencionados, la clase StreamSocket deberá establecerse para usar SSL/TLS en el cifrado.If the protectionLevel parameter is set to Windows.Networking.Sockets.SocketProtectionLevel.Ssl when calling either of the above ConnectAsync methods, the StreamSocket must will be established to use SSL/TLS for encryption. Este valor requiere cifrado y nunca permite el uso de un cifrado NULL.This value requires encryption and never allows a NULL cipher to be used.

La secuencia normal que puedes usar con uno de estos métodos ConnectAsync es la misma.The normal sequence to use with one of these ConnectAsync methods is the same.

El siguiente ejemplo crea un objeto StreamSocket e intenta establecer una conexión al servicio de red y negociar de inmediato el uso de SSL/TLS.The following example creates a StreamSocket and tries to establish a connection to the network service and negotiate immediately to use SSL/TLS. Si la negociación se realiza correctamente, toda comunicación de red que use el objeto StreamSocket entre el cliente y el servidor de red será cifrada.If the negotiation is successful, all network communication using the StreamSocket between the client the network server will be encrypted.

using Windows.Networking;
using Windows.Networking.Sockets;

    // Define some variables and set values
    StreamSocket clientSocket = new StreamSocket();
     
    HostName serverHost = new HostName("www.contoso.com");
    string serverServiceName = "https";
    
    // For simplicity, the sample omits implementation of the
    // NotifyUser method used to display status and error messages 
    
    // Try to connect to contoso using HTTPS (port 443)
    try {

        // Call ConnectAsync method with SSL
        await clientSocket.ConnectAsync(serverHost, serverServiceName, SocketProtectionLevel.Ssl);

        NotifyUser("Connected");
    }
    catch (Exception exception) {
        // If this is an unknown status it means that the error is fatal and retry will likely fail.
        if (SocketError.GetStatus(exception.HResult) == SocketErrorStatus.Unknown) {
            throw;
        }
        
        NotifyUser("Connect failed with error: " + exception.Message);
        // Could retry the connection, but for this simple example
        // just close the socket.
        
        clientSocket.Dispose();
        clientSocket = null; 
    }
           
    // Add code to send and receive data using the clientSocket
    // and then close the clientSocket
#include <winrt/Windows.Networking.Sockets.h>

using namespace winrt;
...
    // Define some variables, and set values.
    Windows::Networking::Sockets::StreamSocket clientSocket;

    Windows::Networking::HostName serverHost{ L"www.contoso.com" };
    winrt::hstring serverServiceName{ L"https" };

    // For simplicity, the sample omits implementation of the
    // NotifyUser method used to display status and error messages.

    // Try to connect to the server using HTTPS and SSL (port 443).
    try
    {
        co_await clientSocket.ConnectAsync(serverHost, serverServiceName, Windows::Networking::Sockets::SocketProtectionLevel::Tls12);
        NotifyUser(L"Connected");
    }
    catch (winrt::hresult_error const& exception)
    {
        NotifyUser(L"Connect failed with error: " + exception.message());
        clientSocket = nullptr;
    }
    // Add code to send and receive data using the clientSocket,
    // then set the clientSocket to nullptr when done to close it.
using Windows::Networking;
using Windows::Networking::Sockets;

    // Define some variables and set values
    StreamSocket^ clientSocket = new ref StreamSocket();
 
    HostName^ serverHost = new ref HostName("www.contoso.com");
    String serverServiceName = "https";

    // For simplicity, the sample omits implementation of the
    // NotifyUser method used to display status and error messages 

    // Try to connect to the server using HTTPS and SSL (port 443)
    task<void>(clientSocket->ConnectAsync(serverHost, serverServiceName, SocketProtectionLevel::SSL)).then([this] (task<void> previousTask) {
        try
        {
            // Try getting all exceptions from the continuation chain above this point.
            previousTask.Get();
            NotifyUser("Connected");
        }
        catch (Exception^ exception)
        {
            NotifyUser("Connect failed with error: " + exception->Message);
            
            clientSocket.Close();
            clientSocket = null;
        }
    });
    // Add code to send and receive data using the clientSocket
    // Then close the clientSocket when done

Usar UpgradeToSslAsyncUse UpgradeToSslAsync

Si tu código usa UpgradeToSslAsync, establece primero una conexión a un servicio de red sin cifrado.When your code uses UpgradeToSslAsync, it first establishes a connection to a network service without encryption. La aplicación puede enviar o recibir algunos datos. A continuación, actualiza la conexión para usar SSL/TLS en todas las comunicaciones.The app may send or receive some data, then upgrade the connection to use SSL/TLS for all further communications.

El método UpgradeToSslAsync usa dos parámetros.The UpgradeToSslAsync method takes two parameters. El parámetro protectionLevel indica el nivel de protección que quieres.The protectionLevel parameter indicates the protection level desired. El parámetro validationHostName es el nombre de host del destino de red remota que se usa para la validación, cuando se actualiza a SSL.The validationHostName parameter is the hostname of the remote network destination that is used for validation when upgrading to SSL. Por lo general, el parámetro validationHostName es el mismo nombre de host que usó la aplicación para establecer inicialmente la conexión.Normally the validationHostName would be the same hostname that the app used to initially establish the connection. Si el parámetro protectionLevel se establece como Windows.System.Socket.SocketProtectionLevel.Ssl al llamar a UpgradeToSslAsync, la clase StreamSocket deberá usar el SSL/TLS para cifrar las posibles comunicaciones con el socket.If the protectionLevel parameter is set to Windows.System.Socket.SocketProtectionLevel.Ssl when calling UpgradeToSslAsync, the StreamSocket must use the SSL/TLS for encryption on further communications over the socket. Este valor requiere cifrado y nunca permite el uso de un cifrado NULL.This value requires encryption and never allows a NULL cipher to be used.

La secuencia normal que puedes usar con el método UpgradeToSslAsync es la siguiente:The normal sequence to use with the UpgradeToSslAsync method is as follows:

El siguiente ejemplo crea una clase StreamSocket e intenta establecer una conexión al servicio de red, enviar algunos datos iniciales y, a continuación, negociar el uso de SSL/TLS.The following example creates a StreamSocket, tries to establish a connection to the network service, sends some initial data, and then negotiates to use SSL/TLS. Si la negociación se realiza correctamente, toda comunicación de red que use la clase StreamSocket entre el cliente y el servidor de red estará cifrada.If the negotiation is successful, all network communication using the StreamSocket between the client and the network server will be encrypted.

using Windows.Networking;
using Windows.Networking.Sockets;
using Windows.Storage.Streams;

    // Define some variables and set values
    StreamSocket clientSocket = new StreamSocket();
 
    HostName serverHost = new HostName("www.contoso.com");
    string serverServiceName = "http";

    // For simplicity, the sample omits implementation of the
    // NotifyUser method used to display status and error messages 

    // Try to connect to contoso using HTTP (port 80)
    try {
        // Call ConnectAsync method with a plain socket
        await clientSocket.ConnectAsync(serverHost, serverServiceName, SocketProtectionLevel.PlainSocket);

        NotifyUser("Connected");

    }
    catch (Exception exception) {
        // If this is an unknown status it means that the error is fatal and retry will likely fail.
        if (SocketError.GetStatus(exception.HResult) == SocketErrorStatus.Unknown) {
            throw;
        }

        NotifyUser("Connect failed with error: " + exception.Message, NotifyType.ErrorMessage);
        // Could retry the connection, but for this simple example
        // just close the socket.

        clientSocket.Dispose();
        clientSocket = null; 
        return;
    }

    // Now try to send some data
    DataWriter writer = new DataWriter(clientSocket.OutputStream);
    string hello = "Hello, World! ☺ ";
    Int32 len = (int) writer.MeasureString(hello); // Gets the UTF-8 string length.
    writer.WriteInt32(len);
    writer.WriteString(hello);
    NotifyUser("Client: sending hello");

    try {
        // Call StoreAsync method to store the hello message
        await writer.StoreAsync();

        NotifyUser("Client: sent data");

        writer.DetachStream(); // Detach stream, if not, DataWriter destructor will close it.
    }
    catch (Exception exception) {
        NotifyUser("Store failed with error: " + exception.Message);
        // Could retry the store, but for this simple example
            // just close the socket.

            clientSocket.Dispose();
            clientSocket = null; 
            return;
    }

    // Now upgrade the client to use SSL
    try {
        // Try to upgrade to SSL
        await clientSocket.UpgradeToSslAsync(SocketProtectionLevel.Ssl, serverHost);

        NotifyUser("Client: upgrade to SSL completed");
           
        // Add code to send and receive data 
        // The close clientSocket when done
    }
    catch (Exception exception) {
        // If this is an unknown status it means that the error is fatal and retry will likely fail.
        if (SocketError.GetStatus(exception.HResult) == SocketErrorStatus.Unknown) {
            throw;
        }

        NotifyUser("Upgrade to SSL failed with error: " + exception.Message);

        clientSocket.Dispose();
        clientSocket = null; 
        return;
    }
#include <winrt/Windows.Networking.Sockets.h>
#include <winrt/Windows.Storage.Streams.h>

using namespace winrt;
using namespace Windows::Storage::Streams;
...
    // Define some variables, and set values.
    Windows::Networking::Sockets::StreamSocket clientSocket;

    Windows::Networking::HostName serverHost{ L"www.contoso.com" };
    winrt::hstring serverServiceName{ L"https" };

    // For simplicity, the sample omits implementation of the
    // NotifyUser method used to display status and error messages. 

    // Try to connect to the server using HTTP (port 80).
    try
    {
        co_await clientSocket.ConnectAsync(serverHost, serverServiceName, Windows::Networking::Sockets::SocketProtectionLevel::PlainSocket);
        NotifyUser(L"Connected");
    }
    catch (winrt::hresult_error const& exception)
    {
        NotifyUser(L"Connect failed with error: " + exception.message());
        clientSocket = nullptr;
    }

    // Now, try to send some data.
    DataWriter writer{ clientSocket.OutputStream() };
    winrt::hstring hello{ L"Hello, World! ☺ " };
    uint32_t len{ writer.MeasureString(hello) }; // Gets the size of the string, in bytes.
    writer.WriteInt32(len);
    writer.WriteString(hello);
    NotifyUser(L"Client: sending hello");

    try
    {
        co_await writer.StoreAsync();
        NotifyUser(L"Client: sent hello");

        writer.DetachStream(); // Detach the stream when you want to continue using it; otherwise, the DataWriter destructor closes it.
    }
    catch (winrt::hresult_error const& exception)
    {
        NotifyUser(L"Store failed with error: " + exception.message());
        // We could retry the store operation. But, for this simple example, just close the socket by setting it to nullptr.
        clientSocket = nullptr;
        co_return;
    }

    // Now, upgrade the client to use SSL.
    try
    {
        co_await clientSocket.UpgradeToSslAsync(Windows::Networking::Sockets::SocketProtectionLevel::Tls12, serverHost);
        NotifyUser(L"Client: upgrade to SSL completed");

        // Add code to send and receive data using the clientSocket,
        // then set the clientSocket to nullptr when done to close it.
    }
    catch (winrt::hresult_error const& exception)
    {
        // If this is an unknown status, then the error is fatal and retry will likely fail.
        Windows::Networking::Sockets::SocketErrorStatus socketErrorStatus{ Windows::Networking::Sockets::SocketError::GetStatus(exception.to_abi()) };
        if (socketErrorStatus == Windows::Networking::Sockets::SocketErrorStatus::Unknown)
        {
            throw;
        }

        NotifyUser(L"Upgrade to SSL failed with error: " + exception.message());
        // We could retry the store operation. But for this simple example, just close the socket by setting it to nullptr.
        clientSocket = nullptr;
        co_return;
    }
using Windows::Networking;
using Windows::Networking::Sockets;
using Windows::Storage::Streams;

    // Define some variables and set values
    StreamSocket^ clientSocket = new ref StreamSocket();
 
    Hostname^ serverHost = new ref HostName("www.contoso.com");
    String serverServiceName = "http";

    // For simplicity, the sample omits implementation of the
    // NotifyUser method used to display status and error messages 

    // Try to connect to contoso using HTTP (port 80)
    task<void>(clientSocket->ConnectAsync(serverHost, serverServiceName, SocketProtectionLevel::PlainSocket)).then([this] (task<void> previousTask) {
        try
        {
            // Try getting all exceptions from the continuation chain above this point.
            previousTask.Get();
            NotifyUser("Connected");
        }
        catch (Exception^ exception)
        {
            NotifyUser("Connect failed with error: " + exception->Message);
 
            clientSocket->Close();
            clientSocket = null;
        }
    });
       
    // Now try to send some data
    DataWriter^ writer = new ref DataWriter(clientSocket.OutputStream);
    String hello = "Hello, World! ☺ ";
    Int32 len = (int) writer->MeasureString(hello); // Gets the UTF-8 string length.
    writer->writeInt32(len);
    writer->writeString(hello);
    NotifyUser("Client: sending hello");

    task<void>(writer->StoreAsync()).then([this] (task<void> previousTask) {
        try {
            // Try getting all exceptions from the continuation chain above this point.
            previousTask.Get();

            NotifyUser("Client: sent hello");

            writer->DetachStream(); // Detach stream, if not, DataWriter destructor will close it.
       }
       catch (Exception^ exception) {
               NotifyUser("Store failed with error: " + exception->Message);
               // Could retry the store, but for this simple example
               // just close the socket.
 
               clientSocket->Close();
               clientSocket = null;
               return
       }
    });

    // Now upgrade the client to use SSL
    task<void>(clientSocket->UpgradeToSslAsync(clientSocket.SocketProtectionLevel.Ssl, serverHost)).then([this] (task<void> previousTask) {
        try {
            // Try getting all exceptions from the continuation chain above this point.
            previousTask.Get();

           NotifyUser("Client: upgrade to SSL completed");
           
           // Add code to send and receive data 
           // Then close clientSocket when done
        }
        catch (Exception^ exception) {
            // If this is an unknown status it means that the error is fatal and retry will likely fail.
            if (SocketError.GetStatus(exception.HResult) == SocketErrorStatus.Unknown) {
                throw;
            }

            NotifyUser("Upgrade to SSL failed with error: " + exception.Message);

            clientSocket->Close();
            clientSocket = null; 
            return;
        }
    });

Crear conexiones WebSocket segurasCreating secure WebSocket connections

Al igual que las conexiones de sockets tradicionales, las conexiones WebSocket también pueden cifrarse mediante el cifrado Seguridad de la capa de transporte (TLS) o Capa de sockets seguros (SSL), cuando se usan las características StreamWebSocket y MessageWebSocket para una aplicación para UWP.Like traditional socket connections, WebSocket connections can also be encrypted with Transport Layer Security (TLS)/Secure Sockets Layer (SSL) when using the StreamWebSocket and MessageWebSocket features for a UWP app. En la mayoría de los casos, querrás usar una conexión WebSocket segura.In most cases you'll want to use a secure WebSocket connection. Esto aumentará las posibilidades de que tu conexión se realice correctamente, ya que muchos servidores proxy rechazarán las conexiones WebSocket no cifradas.This will increase the chances that your connection will succeed, as many proxies will reject unencrypted WebSocket connections.

Para obtener ejemplos sobre cómo crear o actualizar una conexión de sockets segura a un servicio de red, consulta Cómo proteger conexiones WebSocket con TLS/SSL.For examples of how to create, or upgrade to, a secure socket connection to a network service, see How to secure WebSocket connections with TLS/SSL.

Además del cifrado con TLS/SSL, es posible que un servidor necesite un valor de encabezado Sec-WebSocket-Protocol para completar el protocolo de enlace inicial.In addition to TLS/SSL encryption, a server may require a Sec-WebSocket-Protocol header value to complete the initial handshake. Este valor, representado por las propiedades StreamWebSocketInformation.Protocol y MessageWebSocketInformation.Protocol, indica la versión del protocolo de la conexión y permite que el servidor interprete correctamente el protocolo de enlace de apertura y los datos que se intercambian después.This value, represented by the StreamWebSocketInformation.Protocol and MessageWebSocketInformation.Protocol properties, indicate the protocol version of the connection and enables the server to correctly interpret the opening handshake and the data being exchanged afterwards. Mediante esta información del protocolo, si en algún momento el servidor no puede interpretar los datos entrantes de manera segura, se puede cerrar la conexión.Using this protocol information, if at any point if the server cannot interpret the incoming data in a safe manner the connection can be closed.

Si la solicitud inicial del cliente no contiene este valor o proporciona un valor que no coincide con el que espera el servidor, el valor esperado se envía desde el servidor al cliente a modo de error de protocolo de enlace de WebSocket.If the initial request from the client either does not contain this value, or provides a value that doesn't match what the server expects, the expected value is sent from the server to the client on WebSocket handshake error.

AutenticaciónAuthentication

Cómo proporcionar credenciales de autenticación al conectarse a través de la red.How to provide authentication credentials when connecting over the network.

Aprovisionamiento de un certificado de cliente con la clase StreamSocketProviding a client certificate with the StreamSocket class

La clase Windows.Networking.Sockets.StreamSocket admite el uso de SSL/TLS para autenticar el servidor con el que se comunica la aplicación.The Windows.Networking.Sockets.StreamSocket class supports using SSL/TLS to authenticate the server the app is talking to. En algunos casos, la aplicación también debe autenticarse en el servidor mediante un certificado de cliente TLS.In certain cases, the app also needs to authenticate itself to the server using a TLS client certificate. En Windows 10, puedes proporcionar un certificado de cliente en el objeto StreamSocket.Control (se debe establecer antes de iniciar el protocolo de enlace TLS).In Windows 10, you can provide a client certificate on the StreamSocket.Control object (this must be set before the TLS handshake is started). Si el servidor solicita el certificado de cliente, Windows responderá con el certificado proporcionado.If the server requests the client certificate, Windows will respond with the certificate provided.

Este es un fragmento de código que muestra cómo puedes implementar esto:Here is a code snippet showing how to implement this:

var socket = new StreamSocket();
Windows.Security.Cryptography.Certificates.Certificate certificate = await GetClientCert();
socket.Control.ClientCertificate = certificate;
await socket.ConnectAsync(destination, SocketProtectionLevel.Tls12);

Proporcionar credenciales de autenticación a un servicio webProviding authentication credentials to a web service

Las API para redes que permiten que las aplicaciones interactúen con servicios web seguros, proporcionan sus propios métodos para inicializar un cliente o establecer un encabezado de solicitud con credenciales de autenticación de proxy y servidor.The networking APIs that enable apps to interact with secure web services each provide their own methods to either initialize a client or set a request header with server and proxy authentication credentials. Cada método se establece con un objeto PasswordCredential que indica un nombre de usuario, una contraseña y el recurso para el cual se usan estas credenciales.Each method is set with a PasswordCredential object that indicates a user name, password, and the resource for which these credentials are used. En la siguiente tabla, se proporciona una relación de estas API:The following table provides a mapping of these APIs:

WebSocketsWebSockets MessageWebSocketControl.ServerCredentialMessageWebSocketControl.ServerCredential
MessageWebSocketControl.ProxyCredentialMessageWebSocketControl.ProxyCredential
StreamWebSocketControl.ServerCredentialStreamWebSocketControl.ServerCredential
StreamWebSocketControl.ProxyCredentialStreamWebSocketControl.ProxyCredential
Background TransferBackground Transfer BackgroundDownloader.ServerCredentialBackgroundDownloader.ServerCredential
BackgroundDownloader.ProxyCredentialBackgroundDownloader.ProxyCredential
BackgroundUploader.ServerCredentialBackgroundUploader.ServerCredential
BackgroundUploader.ProxyCredentialBackgroundUploader.ProxyCredential
SyndicationSyndication SyndicationClient(PasswordCredential) SyndicationClient(PasswordCredential)
SyndicationClient.ServerCredentialSyndicationClient.ServerCredential
SyndicationClient.ProxyCredentialSyndicationClient.ProxyCredential
AtomPubAtomPub AtomPubClient(PasswordCredential) AtomPubClient(PasswordCredential)
AtomPubClient.ServerCredentialAtomPubClient.ServerCredential
AtomPubClient.ProxyCredentialAtomPubClient.ProxyCredential

Controlar excepciones de redHandling network exceptions

En la mayoría de las áreas de programación, una excepción indica un error o problema significativo, causado por algún error en el programa.In most areas of programming, an exception indicates a significant problem or failure, caused by some flaw in the program. En la programación de red, existe un origen adicional para excepciones: la propia red y la naturaleza de las comunicaciones de red.In network programming, there is an additional source for exceptions: the network itself, and the nature of network communications. Las comunicaciones de red son inherentemente no confiables y están propensas a errores inesperados.Network communications are inherently unreliable and prone to unexpected failure. Para cada una de las formas en que la aplicación usa la conexión de red, debes mantener alguna información de estado; y el código de la aplicación debe controlar las excepciones de red actualizando esa información de estado e iniciando la lógica adecuada para tu aplicación para restablecer o reintentar en caso de errores de comunicación.For each of the ways your app uses networking, you must maintain some state information; and your app code must handle network exceptions by updating that state information and initiating appropriate logic for your app to re-establish or retry communication failures.

Cuando las aplicaciones universales de Windows arrojan una excepción, el controlador de excepciones puede recuperar información más detallada sobre la causa de la excepción para que así puedas comprender mejor el error y tomar las decisiones adecuadas.When Universal Windows apps throw an exception, your exception handler can retrieve more detailed information on the cause of the exception to better understand the failure and make appropriate decisions.

Cada proyección de lenguaje admite un método para obtener acceso a esta información detallada.Each language projection supports a method to access this more detailed information. Una excepción se proyecta como un valor HRESULT en las aplicaciones universales de Windows.An exception projects as an HRESULT value in Universal Windows apps. El archivo de inclusión Winerror.h contiene una lista muy extensa de posibles valores HRESULT, que incluye errores de red.The Winerror.h include file contains a very large list of possible HRESULT values that includes network errors.

Las API para redes admiten distintos métodos para recuperar la información que detalla la causa de una excepción.The networking APIs support different methods for retrieving this detailed information on the cause of an exception.

  • Algunas API proporcionan un método auxiliar que convierte el valor HRESULT de la excepción en un valor de enumeración.Some APIs provide a helper method that converts the HRESULT value from the exception to an enumeration value.
  • Otras API proporcionan un método para recuperar el valor HRESULT real.Other APIs provide a method to retrieve the actual HRESULT value.