Partilhar via


Noções básicas de rede

Coisas que você deve fazer para qualquer aplicativo habilitado para rede.

Capacidades

Para usar a rede, você deve adicionar elementos de capacidade apropriados ao manifesto do aplicativo. Se nenhum recurso de rede for especificado no manifesto do aplicativo, ele não terá nenhum recurso de rede e qualquer tentativa de conexão à rede falhará.

A seguir estão os recursos de rede mais usados.

Capacidade Descrição
internetClient Fornece acesso de saída à Internet e redes em locais públicos, como aeroportos e cafés. A maioria dos aplicativos que exigem acesso à Internet deve usar esse recurso.
servidorClienteInternet Dá ao aplicativo acesso à rede de entrada e saída da Internet e redes em locais públicos, como aeroportos e cafés.
privateNetworkClientServer Dá ao aplicativo acesso à rede de entrada e saída em locais confiáveis do usuário, como casa e trabalho.

Há outros recursos que podem ser necessários para seu aplicativo, em determinadas circunstâncias.

Capacidade Descrição
autenticação empresarial Permite que um aplicativo se conecte a recursos de rede que exigem credenciais de domínio. Por exemplo, um aplicativo que recupera dados de servidores do SharePoint em uma Intranet privada. Com esse recurso, suas credenciais podem ser usadas para acessar recursos de rede em uma rede que requer credenciais. Um aplicativo com esse recurso pode se passar por você na rede. Você não precisa desse recurso para permitir que seu aplicativo acesse a Internet por meio de um proxy de autenticação.

Para obter mais detalhes, consulte a documentação do cenário de capacidades do Enterprise em Capacidades restritas.
proximidade Necessário para comunicação de proximidade com dispositivos próximos ao computador. A proximidade de campo próximo pode ser usada para enviar ou se conectar a um aplicativo em um dispositivo próximo.

Esse recurso permite que um aplicativo acesse a rede para se conectar a um dispositivo próximo, com o consentimento do usuário para enviar um convite ou aceitar um convite.
certificadosDeUtilizadorPartilhados Esse recurso permite que um aplicativo acesse certificados de software e hardware, como certificados de cartão inteligente. Quando esse recurso é invocado em tempo de execução, o usuário deve executar uma ação, como inserir um cartão ou selecionar um certificado.

Com esse recurso, seus certificados de software e hardware ou um cartão inteligente são usados para identificação no aplicativo. Esta capacidade pode ser utilizada pelo seu empregador, banco ou serviços governamentais para identificação.

Comunicar quando a sua aplicação não está em primeiro plano

Ofereça suporte ao seu aplicativo com tarefas em segundo plano contém informações gerais sobre como usar tarefas em segundo plano para trabalhar quando seu aplicativo não está em primeiro plano. Mais especificamente, o seu código deve executar etapas especiais para ser notificado quando não for a aplicação em primeiro plano atual e os dados chegarem pela rede para a aplicação. Você usou gatilhos de canal de controle para essa finalidade no Windows 8 e eles ainda são suportados no Windows 10. Informações completas sobre o uso de gatilhos de canal de controle estão disponíveis aqui. Uma nova tecnologia no Windows 10 fornece melhor funcionalidade com menor sobrecarga para alguns cenários, como soquetes de fluxo habilitados para push: o agente de soquete e gatilhos de atividade de soquete.

Se seu aplicativo usa DatagramSocket, StreamSocketou StreamSocketListener, seu aplicativo pode transferir a propriedade de um soquete aberto para um agente de soquete fornecido pelo sistema e, em seguida, deixar o primeiro plano ou até mesmo encerrar. Quando uma conexão é feita no soquete transferido ou o tráfego chega nesse soquete, seu aplicativo ou sua tarefa em segundo plano designada são ativados. Se o seu aplicativo não estiver em execução, ele será iniciado. Em seguida, o intermediário de soquete notifica o seu aplicativo usando um SocketActivityTrigger que o novo tráfego chegou. O seu aplicativo recupera o soquete do gestor de soquetes e processa o tráfego no soquete. Isso significa que seu aplicativo consome muito menos recursos do sistema quando não está processando ativamente o tráfego de rede.

O broker de sockets destina-se a substituir os Control Channel Triggers onde for aplicável, porque fornece a mesma funcionalidade, mas com menos restrições e uma menor pegada de memória. O agente de soquete pode ser usado por aplicativos que não são aplicativos de tela de bloqueio e é usado da mesma forma em telefones como em outros dispositivos. Os aplicativos não precisam estar em execução quando o tráfego chega para serem ativados pelo agente de soquete. Além disso, o broker de soquetes suporta escuta em soquetes TCP, que os triggers de canal de controlo não suportam.

Escolhendo um gatilho de rede

Existem alguns cenários em que qualquer um dos tipos de gatilho seria adequado. Ao escolher que tipo de gatilho usar em seu aplicativo, considere os seguintes conselhos.

  • Se você estiver usando IXMLHTTPRequest2, System.Net.Http.HttpClient ou System.Net.Http.HttpClientHandler, deverá usar ControlChannelTrigger .
  • Se você estiver usando oStreamSockets habilitado para push, poderá usar gatilhos de canal de controle, mas deve preferir SocketActivityTrigger. A última opção permite que o sistema libere memória e reduza os requisitos de energia quando a conexão não está sendo usada ativamente.
  • Se você quiser minimizar o espaço de memória do seu aplicativo quando ele não estiver atendendo ativamente às solicitações de rede, prefira SocketActivityTrigger quando possível.
  • Se você quiser que seu aplicativo possa receber dados enquanto o sistema estiver no modo de espera conectado, use SocketActivityTrigger.

Para obter detalhes e exemplos de como usar o intermediário de soquete, consulte Comunicações de rede em segundo plano.

Ligações seguras

Secure Sockets Layer (SSL) e o mais recente Transport Layer Security (TLS) são protocolos criptográficos projetados para fornecer autenticação e criptografia para comunicação de rede. Esses protocolos são projetados para evitar escutas e adulterações ao enviar e receber dados da rede. Esses protocolos usam um modelo cliente-servidor para as trocas de protocolo. Esses protocolos também usam certificados digitais e autoridades de certificação para verificar se o servidor é quem afirma ser.

Criando conexões de soquete seguras

Um objeto StreamSocket pode ser configurado para usar SSL/TLS para comunicações entre o cliente e o servidor. Esse suporte para SSL/TLS é limitado ao uso do objeto StreamSocket como o cliente na negociação SSL/TLS. Não é possível usar SSL/TLS com o StreamSocket criado por um StreamSocketListener quando as comunicações de entrada são recebidas, porque a classe StreamSocket não implementa a negociação SSL/TLS como um servidor.

Há duas maneiras de proteger uma conexão StreamSocket com SSL/TLS:

  • ConnectAsync - Faça a conexão inicial com um serviço de rede e negocie imediatamente o uso de SSL/TLS para todas as comunicações.
  • UpgradeToSslAsync - Conecte-se inicialmente a um serviço de rede sem criptografia. O aplicativo pode enviar ou receber dados. Em seguida, atualize a conexão para usar SSL/TLS para todas as comunicações adicionais.

O SocketProtectionLevel especifica o nível de proteção de soquete desejado com o qual o aplicativo deseja estabelecer ou atualizar a conexão. No entanto, o eventual nível de proteção da conexão estabelecida é determinado em um processo de negociação entre ambos os pontos finais da conexão. O resultado pode ser um nível de proteção mais baixo do que aquele que você especificou, se o outro ponto de extremidade solicitar um nível mais baixo.

Depois de a operação assíncrona ser concluída com êxito, poderá recuperar o nível de proteção solicitado, utilizado nas chamadas ConnectAsync de ou UpgradeToSslAsync de , por meio da propriedade StreamSocketinformation.ProtectionLevel . No entanto, isso não reflete o nível de proteção real que a conexão está usando.

Observação

Seu código não deve depender implicitamente do uso de um determinado nível de proteção ou da suposição de que um determinado nível de segurança é usado por padrão. O cenário de segurança muda constantemente, e os protocolos e os níveis de proteção padrão mudam ao longo do tempo para evitar o uso de protocolos com fraquezas conhecidas. Os padrões podem variar dependendo da configuração individual da máquina ou do software instalado e dos patches aplicados. Se o seu aplicativo depender do uso de um nível de segurança específico, você deverá especificar explicitamente esse nível e, em seguida, verificar se ele está realmente em uso na conexão estabelecida.

Utilizar o ConnectAsync

ConnectAsync pode ser usado para estabelecer a conexão inicial com um serviço de rede e, em seguida, negociar imediatamente para usar SSL/TLS para todas as comunicações. Há dois métodos ConnectAsync que suportam a passagem de um parâmetro protectionLevel:

  • ConnectAsync(EndpointPair, SocketProtectionLevel) - Inicia uma operação assíncrona em um objeto StreamSocket para se conectar a um destino de rede remoto especificado como um objeto EndpointPair e umSocketProtectionLevel .
  • ConnectAsync(HostName, String, SocketProtectionLevel) - Inicia uma operação assíncrona em um objeto StreamSocket para se conectar a um destino remoto especificado por um nome de host remoto, um nome de serviço remoto e umSocketProtectionLevel .

Se o parâmetro protectionLevel estiver definido como Windows.Networking.Sockets.SocketProtectionLevel.Ssl ao chamar um dos métodos ConnectAsync acima, o StreamSocket deverá ser configurado para utilizar SSL/TLS para criptografia. Esse valor requer criptografia e nunca permite que uma cifra NULL seja usada.

A sequência normal a ser usada com um desses métodos ConnectAsync é a mesma.

  • Crie um StreamSocket.
  • Caso seja necessária uma opção avançada no socket, use a propriedade StreamSocket.Control para obter a instância de StreamSocketControl associada a um objeto StreamSocket. Defina uma propriedade no StreamSocketControl.
  • Chame um dos métodos ,, ConnectAsync acima para iniciar uma operação de conexão a um destino remoto e negociar imediatamente o uso de SSL/TLS.
  • A força do SSL realmente negociada usando ConnectAsync pode ser determinada obtendo a propriedade StreamSocketinformation.ProtectionLevel após a operação assíncrona ter sido concluída com êxito.

O exemplo a seguir cria um StreamSocket e tenta estabelecer uma conexão com o serviço de rede e negociar imediatamente para usar SSL/TLS. Se a negociação for bem-sucedida, toda a comunicação de rede usando o StreamSocket entre o cliente e o servidor de rede será criptografada.

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 UpgradeToSslAsync

Quando seu código usa UpgradeToSslAsync, ele primeiro estabelece uma conexão com um serviço de rede sem criptografia. O aplicativo pode enviar ou receber alguns dados e, em seguida, atualizar a conexão para usar SSL/TLS para todas as comunicações adicionais.

O método UpgradeToSslAsync usa dois parâmetros. O parâmetro protectionLevel indica o nível de proteção desejado. O parâmetro validationHostName é o nome do host do destino da rede remota utilizado para validação ao atualizar para SSL. Normalmente, o validationHostName seria o mesmo nome de host que o aplicativo usou inicialmente para estabelecer a conexão. Se o parâmetro protectionLevel estiver definido como Windows.System.Socket.SocketProtectionLevel.Ssl ao chamar UpgradeToSslAsync, o StreamSocket deverá usar o SSL/TLS para criptografia em comunicações adicionais pelo soquete. Esse valor requer criptografia e nunca permite que uma cifra NULL seja usada.

A sequência normal a ser usada com o método UpgradeToSslAsync é a seguinte:

  • Crie um StreamSocket.
  • Caso seja necessária uma opção avançada no socket, use a propriedade StreamSocket.Control para obter a instância de StreamSocketControl associada a um objeto StreamSocket. Defina uma propriedade no StreamSocketControl.
  • Se algum dado precisar ser enviado e recebido sem criptografia, envie-o agora.
  • Chame o método UpgradeToSslAsync para iniciar uma operação de atualização da conexão para usar SSL/TLS.
  • A força do SSL realmente negociada usando UpgradeToSslAsync pode ser determinada obtendo a propriedade StreamSocketinformation.ProtectionLevel depois que a operação assíncrona for concluída com êxito.

O exemplo a seguir cria um StreamSocket, tenta estabelecer uma conexão com o serviço de rede, envia alguns dados iniciais e, em seguida, negocia para usar SSL/TLS. Se a negociação for bem-sucedida, toda a comunicação de rede usando o StreamSocket entre o cliente e o servidor de rede será criptografada.

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

Criando conexões WebSocket seguras

Como as conexões de soquete tradicionais, as conexões WebSocket também podem ser criptografadas com TLS/SSL (Transport Layer Security/Secure Sockets Layer) ao usar os recursos de StreamWebSocket e MessageWebSocket para um aplicativo UWP. Na maioria dos casos, você vai querer usar uma conexão WebSocket segura. Isso aumentará as chances de que sua conexão seja bem-sucedida, já que muitos proxies rejeitarão conexões WebSocket não criptografadas.

Para obter exemplos de como criar ou atualizar para uma conexão de soquete segura para um serviço de rede, consulte Como proteger conexões WebSocket com TLS/SSL.

Além da criptografia TLS/SSL, um servidor pode exigir um valor de cabeçalho Sec-WebSocket-Protocol para concluir o handshake inicial. Este valor, representado pelas propriedades StreamWebSocketInformation.Protocol e MessageWebSocketInformation.Protocol, indica a versão do protocolo da conexão e permite que o servidor interprete corretamente o handshake de abertura e os dados que estão sendo trocados posteriormente. Usando essas informações de protocolo, se em algum momento o servidor não puder interpretar os dados recebidos de maneira segura, a conexão poderá ser fechada.

Se a solicitação inicial do cliente não contiver esse valor ou fornecer um valor que não corresponda ao que o servidor espera, o valor esperado será enviado do servidor para o cliente no erro de handshake WebSocket.

Autenticação

Como fornecer credenciais de autenticação ao conectar-se pela rede.

Fornecendo um certificado de cliente com a classe StreamSocket

A classe Windows.Networking.Sockets.StreamSocket oferece suporte ao uso de SSL/TLS para autenticar o servidor com o qual o aplicativo está falando. Em certos casos, o aplicativo também precisa se autenticar no servidor usando um certificado de cliente TLS. No Windows 10, você pode fornecer um certificado de cliente no objeto StreamSocket.Control (isso deve ser definido antes que o handshake TLS seja iniciado). Se o servidor solicitar o certificado de cliente, o Windows responderá com o certificado fornecido.

Aqui está um trecho de código mostrando como implementar isso:

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

Fornecendo credenciais de autenticação para um serviço Web

As APIs de rede que permitem que os aplicativos interajam com serviços Web seguros fornecem seus próprios métodos para inicializar um cliente ou definir um cabeçalho de solicitação com credenciais de autenticação de servidor e proxy. Cada método é definido com um objeto PasswordCredential que indica um nome de usuário, senha e o recurso para o qual essas credenciais são usadas. A tabela a seguir fornece um mapeamento dessas APIs:

WebSockets MessageWebSocketControl.ServerCredential
MessageWebSocketControl.ProxyCredential
StreamWebSocketControl.ServerCredential
StreamWebSocketControl.ProxyCredential
Transferência em segundo plano BackgroundDownloader.ServerCredential
BackgroundDownloader.ProxyCredential
BackgroundUploader.ServerCredential
BackgroundUploader.ProxyCredential
Sindicalização SyndicationClient(CredencialDeSenha)
SyndicationClient.ServerCredential
SyndicationClient.ProxyCredential
AtomPub AtomPubClient(PasswordCredential)
AtomPubClient.ServerCredential
AtomPubClient.ProxyCredential

Tratamento de exceções de rede

Na maioria das áreas de programação, uma exceção indica um problema ou falha significativa, causada por alguma falha no programa. Na programação de redes, existe uma fonte adicional de exceções: a própria rede e a natureza das comunicações em rede. As comunicações de rede são inerentemente não confiáveis e propensas a falhas inesperadas. Para cada uma das maneiras como seu aplicativo usa a rede, você deve manter algumas informações de estado; E o código do seu aplicativo deve lidar com exceções de rede atualizando essas informações de estado e iniciando a lógica apropriada para que seu aplicativo restabeleça ou tente novamente falhas de comunicação.

Quando os aplicativos universais do Windows lançam uma exceção, seu manipulador de exceções pode recuperar informações mais detalhadas sobre a causa da exceção para entender melhor a falha e tomar as decisões apropriadas.

Cada projeção de linguagem suporta um método para acessar essas informações mais detalhadas. Uma exceção é projetada como um valor HRESULT em aplicativos universais do Windows. O arquivo Winerror.h include contém uma lista muito grande de possíveis HRESULT valores, incluindo erros de rede.

As APIs de rede oferecem suporte a diferentes métodos para recuperar essas informações detalhadas sobre a causa de uma exceção.

  • Algumas APIs fornecem um método auxiliar que converte o valor HRESULT da exceção para um valor de enumeração.
  • Outras APIs fornecem um método para recuperar o valor real do HRESULT.