Partager via


Principes de base de la mise en réseau

Ce que vous devez faire pour n’importe quelle application compatible réseau.

Capacités

Pour utiliser la mise en réseau, vous devez ajouter des éléments de fonctionnalité appropriés au manifeste de votre application. Si aucune fonctionnalité réseau n’est spécifiée dans le manifeste de votre application, votre application n’aura aucune fonctionnalité de mise en réseau et toute tentative de connexion au réseau échouera.

Voici les fonctionnalités de mise en réseau les plus utilisées.

Capacité Descriptif
InternetClient Fournit un accès sortant à Internet et aux réseaux dans les lieux publics, tels que les aéroports et les cafés. La plupart des applications qui nécessitent un accès Internet doivent utiliser cette fonctionnalité.
InternetClientServer Donne à l’application un accès réseau entrant et sortant à partir d’Internet et de réseaux dans des lieux publics tels que les aéroports et les cafés.
privateNetworkClientServer Donne à l’application un accès réseau entrant et sortant aux emplacements approuvés de l’utilisateur, tels que la maison et le travail.

Il existe d’autres fonctionnalités qui peuvent être nécessaires pour votre application, dans certaines circonstances.

Capacité Descriptif
authentificationEntreprise Permet à une application de se connecter aux ressources réseau qui nécessitent des informations d’identification de domaine. Par exemple, une application qui récupère des données à partir de serveurs SharePoint sur un intranet privé. Avec cette fonctionnalité, vos informations d’identification peuvent être utilisées pour accéder aux ressources réseau sur un réseau qui nécessite des informations d’identification. Une application avec cette fonctionnalité peut usurper votre identité sur le réseau. Vous n’avez pas besoin de cette fonctionnalité pour permettre à votre application d’accéder à Internet via un proxy d’authentification.

Pour plus d'informations, consultez la documentation relative au scénario de capacité d'entreprise dans les capacités restreintes .
de proximité Obligatoire pour la communication en champ proche avec des appareils à proximité de l’ordinateur. La communication en champ proche (NFC) peut être utilisée pour envoyer des données ou pour se connecter à une application sur un appareil à proximité.

Cette fonctionnalité permet à une application d’accéder au réseau pour se connecter à un appareil de proximité, avec le consentement de l’utilisateur pour envoyer une invitation ou accepter une invitation.
certificatsUtilisateursPartagés Cette fonctionnalité permet à une application d’accéder aux certificats logiciels et matériels, tels que les certificats de carte à puce. Lorsque cette fonctionnalité est appelée au moment de l’exécution, l’utilisateur doit prendre des mesures, telles que l’insertion d’une carte ou la sélection d’un certificat.

Avec cette fonctionnalité, vos certificats logiciels et matériels ou une carte à puce sont utilisés pour l’identification dans l’application. Cette fonctionnalité peut être utilisée par votre employeur, votre banque ou les services gouvernementaux pour l’identification.

Communication lorsque votre application n’est pas au premier plan

La prise en charge de votre application avec des tâches en arrière-plan contient des informations générales sur l’utilisation des tâches en arrière-plan pour effectuer des tâches lorsque votre application n’est pas au premier plan. Plus précisément, votre code doit prendre des mesures spéciales pour être averti lorsqu’il n'est pas l'application active au premier plan, et que des données lui parviennent via le réseau. Vous avez utilisé les déclencheurs de canal de contrôle à cet effet dans Windows 8, et ils sont toujours pris en charge dans Windows 10. Des informations complètes sur l’utilisation des déclencheurs de canal de contrôle sont disponibles ici. Une nouvelle technologie dans Windows 10 offre de meilleures fonctionnalités, tout en réduisant la charge pour certains scénarios, tels que les sockets de flux activés par push : le courtier de sockets et les déclencheurs d'activité des sockets.

Si votre application utilise DatagramSocket, StreamSocket ou StreamSocketListener, votre application peut transférer la propriété d’un socket ouvert à un répartiteur de sockets fourni par le système, puis quitter le premier plan, ou même se terminer. Lorsqu’une connexion est établie sur le socket transféré ou que le trafic arrive sur ce socket, votre application ou sa tâche en arrière-plan désignée sont activées. Si votre application n’est pas en cours d’exécution, elle est démarrée. Le répartiteur de sockets avertit ensuite votre application à l’aide d’un SocketActivityTrigger que le nouveau trafic est arrivé. Votre application récupère le socket du gestionnaire de sockets et traite le trafic sur le socket. Cela signifie que votre application consomme beaucoup moins de ressources système lorsqu’elle ne traite pas activement le trafic réseau.

Le répartiteur de sockets est destiné à remplacer les déclencheurs de canal de contrôle où il s’applique, car il fournit la même fonctionnalité, mais avec moins de restrictions et un encombrement mémoire plus faible. Le répartiteur de sockets peut être utilisé par les applications qui ne sont pas des applications d’écran de verrouillage, et elle est utilisée de la même façon sur les téléphones que sur d’autres appareils. Les applications n’ont pas besoin d’être en cours d’exécution lorsque le trafic arrive pour être activé par le répartiteur de sockets. Et le répartiteur de sockets prend en charge l’écoute sur les sockets TCP, ce que les déclencheurs de canal de contrôle ne permettent pas.

Choix d’un déclencheur réseau

Il existe certains scénarios où l’un ou l’autre type de déclencheur convient. Lorsque vous choisissez le type de déclencheur à utiliser dans votre application, tenez compte des conseils suivants.

Pour plus d'informations et d'exemples d'utilisation du broker de sockets, consultez les communications réseau en arrière-plan.

Connexions sécurisées

Ssl (Secure Sockets Layer) et tls (Transport Layer Security) les plus récents sont des protocoles de chiffrement conçus pour fournir l’authentification et le chiffrement pour la communication réseau. Ces protocoles sont conçus pour empêcher l’écoute et la falsification d’enregistrement lors de l’envoi et de la réception de données réseau. Ces protocoles utilisent un modèle client-serveur pour les échanges de protocole. Ces protocoles utilisent également des certificats numériques et des autorités de certification pour vérifier que le serveur est celui qu’il prétend être.

Création de connexions de sockets sécurisés

Un objet StreamSocket peut être configuré pour utiliser SSL/TLS pour les communications entre le client et le serveur. Cette prise en charge de SSL/TLS est limitée à l’utilisation de l’objet StreamSocket en tant que client dans la négociation SSL/TLS. Vous ne pouvez pas utiliser SSL/TLS avec StreamSocket créé par un StreamSocketListener lorsque les communications entrantes sont reçues, car la négociation SSL/TLS en tant que serveur n’est pas implémentée par la classe StreamSocket .

Il existe deux façons de sécuriser une connexion StreamSocket avec SSL/TLS :

  • ConnectAsync : établissez la connexion initiale à un service réseau et négociez immédiatement pour utiliser SSL/TLS pour toutes les communications.
  • UpgradeToSslAsync - Connectez-vous initialement à un service réseau sans chiffrement. L’application peut envoyer ou recevoir des données. Ensuite, mettez à niveau la connexion pour utiliser SSL/TLS pour toutes les communications supplémentaires.

SocketProtectionLevel spécifie le niveau de protection de socket souhaité avec lequel l’application souhaite établir ou mettre à niveau la connexion. Toutefois, le niveau de protection éventuel de la connexion établie est déterminé dans un processus de négociation entre les deux points de terminaison de la connexion. Le résultat peut être un niveau de protection inférieur à celui que vous avez spécifié, si l’autre point de terminaison demande un niveau inférieur.

Une fois l’opération asynchrone terminée, vous pouvez récupérer le niveau de protection demandé utilisé dans l’appel ConnectAsync ou UpgradeToSslAsync via la propriété StreamSocketinformation.ProtectionLevel . Toutefois, cela ne reflète pas le niveau de protection réel utilisé par la connexion.

Remarque

Votre code ne doit pas dépendre implicitement de l’utilisation d’un niveau de protection particulier ou de l’hypothèse qu’un niveau de sécurité donné est utilisé par défaut. Le paysage de la sécurité change constamment, et les protocoles et les niveaux de protection par défaut changent au fil du temps afin d’éviter l’utilisation de protocoles avec des faiblesses connues. Les valeurs par défaut peuvent varier en fonction de la configuration de l’ordinateur, ou du logiciel installé et des correctifs appliqués. Si votre application dépend de l’utilisation d’un niveau de sécurité particulier, vous devez spécifier explicitement ce niveau, puis vérifier qu’il est réellement utilisé sur la connexion établie.

Utiliser ConnectAsync

ConnectAsync peut être utilisé pour établir la connexion initiale avec un service réseau, puis négocier immédiatement pour utiliser SSL/TLS pour toutes les communications. Il existe deux méthodes ConnectAsync qui prennent en charge la transmission d’un paramètre protectionLevel :

Si le paramètre protectionLevel est défini sur Windows.Networking.Sockets.Sockets.SocketProtectionLevel.Ssl lors de l’appel de l’une des méthodes ConnectAsync ci-dessus, streamSocket doit être établi pour utiliser SSL/TLS pour le chiffrement. Cette valeur nécessite le chiffrement et n’autorise jamais l’utilisation d’un chiffrement NULL.

La séquence normale à utiliser avec l’une de ces méthodes ConnectAsync est la même.

  • Créez un StreamSocket.
  • Si une option avancée sur le socket est nécessaire, utilisez la propriété StreamSocket.Control pour obtenir l’instance StreamSocketControl associée à un objet StreamSocket . Définissez une propriété sur le StreamSocketControl.
  • Appelez l’une des méthodes ConnectAsync ci-dessus pour démarrer une opération pour vous connecter à une destination distante et négocier immédiatement l’utilisation de SSL/TLS.
  • La force SSL réellement négociée à l’aide de ConnectAsync peut être déterminée en obtenant la propriété StreamSocketInformation.ProtectionLevel une fois que l'opération asynchrone est terminée avec succès.

L’exemple suivant crée un StreamSocket et tente d’établir une connexion au service réseau et de négocier immédiatement pour utiliser SSL/TLS. Si la négociation réussit, toutes les communications réseau utilisant StreamSocket entre le client le serveur réseau sont chiffrées.

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

Utiliser UpgradeToSslAsync

Lorsque votre code utilise UpgradeToSslAsync, il établit d’abord une connexion à un service réseau sans chiffrement. L’application peut envoyer ou recevoir des données, puis mettre à niveau la connexion pour utiliser SSL/TLS pour toutes les communications supplémentaires.

La méthode UpgradeToSslAsync prend deux paramètres. Le paramètre protectionLevel indique le niveau de protection souhaité. Le paramètre validationHostName est le nom d’hôte de la destination réseau distante utilisée pour la validation lors de la mise à niveau vers SSL. Normalement, le nom d’hôte validationHostName est le même que celui utilisé par l’application pour établir initialement la connexion. Si le paramètre protectionLevel est défini sur Windows.System.Socket.SocketProtectionLevel.Ssl lors de l’appel de UpgradeToSslAsync, StreamSocket doit utiliser le protocole SSL/TLS pour le chiffrement sur d’autres communications via le socket. Cette valeur nécessite le chiffrement et n’autorise jamais l’utilisation d’un chiffrement NULL.

La séquence normale à utiliser avec la méthode UpgradeToSslAsync est la suivante :

  • Créez un StreamSocket.
  • Si une option avancée sur le socket est nécessaire, utilisez la propriété StreamSocket.Control pour obtenir l’instance StreamSocketControl associée à un objet StreamSocket . Définissez une propriété sur le StreamSocketControl.
  • Si des données doivent être envoyées et reçues non chiffrées, envoyez-la maintenant.
  • Appelez la méthode UpgradeToSslAsync pour démarrer une opération de mise à niveau de la connexion pour utiliser SSL/TLS.
  • La force SSL réellement négociée à l’aide de UpgradeToSslAsync peut être déterminée en obtenant la propriété StreamSocketinformation.ProtectionLevel une fois l’opération asynchrone terminée avec succès.

L’exemple suivant crée un StreamSocket, tente d’établir une connexion au service réseau, envoie des données initiales, puis négocie l’utilisation de SSL/TLS. Si la négociation réussit, toutes les communications réseau utilisant StreamSocket entre le client et le serveur réseau sont chiffrées.

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;
        }
    });

Création de connexions WebSocket sécurisées

Comme les connexions de socket traditionnelles, les connexions WebSocket peuvent également être chiffrées avec TLS (Transport Layer Security)/Secure Sockets Layer (SSL) lors de l’utilisation des fonctionnalités StreamWebSocket et MessageWebSocket pour une application UWP. Dans la plupart des cas, vous souhaiterez utiliser une connexion WebSocket sécurisée. Cela augmente les chances que votre connexion réussisse, car de nombreux proxys rejettent les connexions WebSocket non chiffrées.

Pour obtenir des exemples de création ou de mise à niveau vers une connexion de socket sécurisé à un service réseau, consultez Comment sécuriser les connexions WebSocket avec TLS/SSL.

En plus du chiffrement TLS/SSL, un serveur peut nécessiter une valeur d’en-tête Sec-WebSocket-Protocol pour terminer l’établissement d’une liaison initiale. Cette valeur, représentée par les propriétés StreamWebSocketInformation.Protocol et MessageWebSocketInformation.Protocol , indique la version du protocole de la connexion et permet au serveur d’interpréter correctement l’établissement d’une liaison ouvrante et les données échangées ultérieurement. À l’aide de ces informations de protocole, le cas échéant, si le serveur ne peut pas interpréter les données entrantes de manière sécurisée, la connexion peut être fermée.

Si la requête initiale du client ne contient pas cette valeur, ou fournit une valeur qui ne correspond pas à ce que le serveur attend, la valeur attendue est envoyée du serveur au client en cas d'erreur lors de la négociation du WebSocket.

Authentification

Comment fournir des informations d’identification d’authentification lors de la connexion sur le réseau.

Fourniture d’un certificat client avec la classe StreamSocket

La classe Windows.Networking.Sockets.StreamSocket prend en charge l’utilisation de SSL/TLS pour authentifier le serveur auquel l’application parle. Dans certains cas, l’application doit également s’authentifier auprès du serveur à l’aide d’un certificat client TLS. Dans Windows 10, vous pouvez fournir un certificat client sur l’objet StreamSocket.Control (cela doit être défini avant le démarrage de l’établissement d’une liaison TLS). Si le serveur demande le certificat client, Windows répond avec le certificat fourni.

Voici un extrait de code montrant comment implémenter ceci :

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

Fournir des informations d’identification d’authentification à un service web

Les API réseau qui permettent aux applications d’interagir avec des services web sécurisés fournissent chacune leurs propres méthodes pour initialiser un client ou définir un en-tête de requête avec les informations d’identification d’authentification du serveur et du proxy. Chaque méthode est définie avec un objet PasswordCredential qui indique un nom d’utilisateur, un mot de passe et la ressource pour laquelle ces informations d’identification sont utilisées. Le tableau suivant fournit un mappage de ces API :

WebSockets MessageWebSocketControl.ServerCredential
MessageWebSocketControl.ProxyCredential
StreamWebSocketControl.ServerCredential
StreamWebSocketControl.ProxyCredential
Transfert en arrière-plan BackgroundDownloader.ServerCredential
BackgroundDownloader.ProxyCredential
BackgroundUploader.ServerCredential
BackgroundUploader.ProxyCredential
syndication SyndicationClient(PasswordCredential)
SyndicationClient.ServerCredential
SyndicationClient.ProxyCredential
AtomPub AtomPubClient(PasswordCredential)
AtomPubClient.ServerCredential
AtomPubClient.ProxyCredential

Gestion des exceptions réseau

Dans la plupart des domaines de la programmation, une exception indique un problème ou un échec significatif, provoqué par une faille dans le programme. Dans la programmation réseau, il existe une source supplémentaire pour les exceptions : le réseau lui-même et la nature des communications réseau. Les communications réseau sont intrinsèquement peu fiables et sujettes à une défaillance inattendue. Pour chacune des façons dont votre application utilise la mise en réseau, vous devez conserver des informations d’état ; et votre code d’application doit gérer les exceptions réseau en mettant à jour ces informations d’état et en lançant la logique appropriée pour que votre application réinscrire ou réessayer des échecs de communication.

Lorsque les applications Windows universelles lèvent une exception, votre gestionnaire d’exceptions peut récupérer des informations plus détaillées sur la cause de l’exception pour mieux comprendre l’échec et prendre les décisions appropriées.

Chaque projection de langage prend en charge une méthode pour accéder à ces informations plus détaillées. Une exception se présente sous la forme d'une valeur HRESULT dans les applications Windows universelles. Le fichier Include Winerror.h contient une très grande liste de valeurs HRESULT possibles qui incluent des erreurs réseau.

Les API réseau prennent en charge différentes méthodes pour récupérer ces informations détaillées à la cause d’une exception.

  • Certaines API fournissent une méthode d’assistance qui convertit la valeur HRESULT de l’exception en valeur d’énumération.
  • D'autres API fournissent une méthode pour récupérer la véritable valeur HRESULT .