Основы работы в сети

Действия, которые необходимо сделать для любого приложения с поддержкой сети.

Возможности

Чтобы использовать сеть, необходимо добавить соответствующие элементы возможностей в манифест приложения. Если в манифесте приложения нет сетевых возможностей, приложение не сможет подключиться к сети, и любая попытка подключиться к сети завершится ошибкой.

Ниже приведены наиболее используемые сетевые возможности.

Способность Описание
InternetClient Предоставляет исходящий доступ к Интернету и сетям в общественных местах, таких как аэропорты и кафе. Большинство приложений, которым требуется доступ к Интернету, должны использовать эту возможность.
интернетКлиентСервер Предоставляет приложению входящий и исходящий сетевой доступ из Интернета и сетей в общественных местах, таких как аэропорты и кафе.
privateNetworkClientServer Предоставляет приложению входящий и исходящий сетевой доступ в надежных местах пользователя, например дома и работы.

Существуют и другие возможности, которые могут потребоваться для вашего приложения в определенных обстоятельствах.

Способность Описание
аутентификация предприятия Позволяет приложению подключаться к сетевым ресурсам, которым требуются учетные данные домена. Например, приложение, которое извлекает данные с серверов SharePoint в частной интрасети. С помощью этой возможности учетные данные можно использовать для доступа к сетевым ресурсам в сети, требующей учетных данных. Приложение с этой возможностью может олицетворить вас в сети. Для доступа приложения к Интернету через прокси-сервер проверки подлинности не требуется.

Дополнительные сведения см. в документации по сценарию возможностей Enterprise в Ограниченных возможностях .
близость Требуется для ближней связи с устройствами в непосредственной близости от компьютера. Технология ближнего радиуса действия может использоваться для отправки данных или подключения к приложению на соседнем устройстве.

Эта возможность позволяет приложению получить доступ к сети для подключения к устройству в близком расположении с согласием пользователя на отправку приглашения или принятие приглашения.
общие пользовательские сертификаты Эта возможность позволяет приложению получать доступ к сертификатам программного обеспечения и оборудования, таким как сертификаты смарт-карт. Когда эта возможность вызывается во время выполнения, пользователь должен принять меры, такие как вставка карточки или выбор сертификата.

Благодаря этой возможности сертификаты программного обеспечения и оборудования или смарт-карты используются для идентификации в приложении. Эта возможность может использоваться вашим работодателем, банком или государственными службами для идентификации.

Обмен данными, когда ваше приложение не находится на переднем плане

Поддержка приложения с фоновыми задачами содержит общие сведения об использовании фоновых задач для выполнения работы, если приложение не находится на переднем плане. В частности, ваш код должен выполнять специальные действия, чтобы получать уведомления, когда он не является текущим приложением, находящимся на переднем плане, и когда для него поступают данные через сеть. Для этой цели вы использовали триггеры канала управления в Windows 8, и они по-прежнему поддерживаются в Windows 10. Полные сведения об использовании триггеров канала управления доступны здесь. Новая технология в Windows 10 обеспечивает более высокую функциональность с меньшими затратами для некоторых сценариев, таких как сокеты потоков с поддержкой push-уведомлений: брокер сокетов и триггеры действий сокетов.

Если приложение использует DatagramSocket, StreamSocketили StreamSocketListener, ваше приложение может передать владение открытым сокетом брокеру сокета, предоставленному системой, а затем оставить передний план или даже завершить работу. Когда подключение выполняется на перенесенном сокете или трафик поступает на этот сокет, то активируется ваше приложение или назначенная фоновая задача. Если приложение не запущено, оно запускается. Затем брокер сокетов уведомляет приложение с помощью SocketActivityTrigger, что новый трафик прибыл. Приложение забирает сокет у брокера сокетов и обрабатывает трафик в этом сокете. Это означает, что приложение потребляет гораздо меньше системных ресурсов, если он не активно обрабатывает сетевой трафик.

Брокер сокетов предназначен для замены триггеров канала управления, где это применимо, так как он предоставляет те же функции, но с меньшими ограничениями и меньшим объемом памяти. Брокер сокетов можно использовать не только в приложениях экрана блокировки, но и в других приложениях, и используется он на телефонах так же, как на других устройствах. Приложения не должны работать при поступлении трафика для активации брокером сокетов. И брокер сокетов поддерживает прослушивание на сокетах TCP, что триггеры канала управления не поддерживают.

Выбор сетевого триггера

Существуют некоторые сценарии, в которых любой тип триггера подходит. При выборе типа триггера, используемого в приложении, рассмотрите следующие советы.

  • Если вы используете IXMLHTTPRequest2, System.Net.Http.HttpClient или System.Net.HttpClientHandler, необходимо использовать ControlChannelTrigger.
  • Если вы используете StreamSocketsс поддержкой push-уведомлений, можно использовать триггеры канала управления, но предпочтительнее использовать SocketActivityTrigger. Последний выбор позволяет системе освободить память и уменьшить требования к мощности, если подключение не используется.
  • Если вы хотите свести к минимуму объем памяти приложения, если он не активно обслуживает сетевые запросы, предпочесть, SocketActivityTrigger, когда это возможно.
  • Если вы хотите, чтобы приложение могло получать данные во время работы системы в режиме "Подключенный режим ожидания", используйте SocketActivityTrigger.

Для получения дополнительных сведений и примеров использования брокера сокетов см. раздел сетевые коммуникации в фоновом режиме.

Защищенные подключения

Безопасный уровень сокетов (SSL) и более поздний протокол TLS — это криптографические протоколы, предназначенные для проверки подлинности и шифрования для сетевого взаимодействия. Эти протоколы предназначены для предотвращения перехвата и изменения при отправке и получении сетевых данных. Эти протоколы используют модель клиентского сервера для обмена протоколами. Эти протоколы также используют цифровые сертификаты и центры сертификации, чтобы убедиться, что сервер является тем, кто он утверждает.

Создание безопасных соединений сокета

Объект StreamSocket можно настроить для обмена данными между клиентом и сервером с помощью SSL/TLS. Эта поддержка SSL/TLS ограничена использованием объекта StreamSocket в качестве клиента в согласовании SSL/TLS. Вы не можете использовать SSL/TLS с StreamSocket, созданным StreamSocketListener при получении входящих сообщений, потому что согласование SSL/TLS как сервера не реализовано в классе StreamSocket.

Существует два способа защиты подключения StreamSocket с помощью SSL/TLS:

  • ConnectAsync — сделайте начальное подключение к сетевой службе и немедленно согласовывайте использование SSL/TLS для всех коммуникаций.
  • UpgradeToSslAsync — изначально подключитесь к сетевой службе без шифрования. Приложение может отправлять или получать данные. Затем обновите подключение, чтобы использовать SSL/TLS для всех дальнейших подключений.

SocketProtectionLevel указывает требуемый уровень защиты сокета, с которым приложение хочет установить или обновить подключение. Однако конечный уровень защиты установленного соединения определяется в процессе согласования между обеими конечными точками подключения. Результатом может быть более низкий уровень защиты, чем указанный, если другая конечная точка запрашивает более низкий уровень.

После успешного выполнения асинхронной операции вы можете получить запрошенный уровень защиты, используемый в вызовах ConnectAsync или UpgradeToSslAsync, через свойство StreamSocketInformation.ProtectionLevel. Однако это не отражает фактический уровень защиты, используемый соединением.

Замечание

Код не должен неявно зависеть от использования определенного уровня защиты или от предположения, что заданный уровень безопасности используется по умолчанию. Ландшафт безопасности постоянно изменяется, а протоколы и уровни защиты по умолчанию изменяются со временем, чтобы избежать использования протоколов с известными слабыми местами. Значения по умолчанию могут отличаться в зависимости от конфигурации отдельного компьютера или установленного программного обеспечения и примененных исправлений. Если приложение зависит от использования определенного уровня безопасности, необходимо явно указать этот уровень, а затем убедиться, что он фактически используется для установленного подключения.

Использование ConnectAsync

ConnectAsync можно использовать для установления начального подключения к сетевой службе, а затем немедленно согласовывать использование SSL/TLS для всех коммуникаций. Существует два метода ConnectAsync, поддерживающие передачу параметра protectionLevel:

Если для параметра protectionLevel установлено значение Windows.Networking.Sockets.SocketProtectionLevel.Ssl при вызове любого из указанных выше методов ConnectAsync, необходимо установить StreamSocket для использования SSL/TLS при шифровании. Это значение требует шифрования и никогда не позволяет использовать шифр NULL.

Обычная последовательность, используемая с одним из этих методов ConnectAsync, совпадает.

  • Создайте StreamSocket.
  • Если требуется дополнительный параметр сокета, используйте свойство StreamSocket.Control , чтобы получить экземпляр StreamSocketControl , связанный с объектом StreamSocket . Установите свойство на StreamSocketControl.
  • Вызовите один из описанных выше методов ConnectAsync, чтобы запустить операцию для подключения к удаленному месту назначения и немедленно согласовать использование SSL/TLS.
  • Фактически согласованная сила SSL с использованием ConnectAsync может быть определена путём получения свойства StreamSocketInformation.ProtectionLevel после успешного завершения асинхронной операции.

В следующем примере создается StreamSocket и пытается установить подключение к сетевой службе и немедленно согласовать использование SSL/TLS. Если согласование выполнено успешно, все сетевое взаимодействие с помощью StreamSocket между клиентом, сетевым сервером будет зашифровано.

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

Используйте UpgradeToSslAsync

Когда ваш код использует UpgradeToSslAsync, сначала устанавливается подключение к сетевой службе без шифрования. Приложение может отправлять или получать некоторые данные, а затем обновить подключение, чтобы использовать SSL/TLS для всех дальнейших коммуникаций.

Метод UpgradeToSslAsync принимает два параметра. Параметр protectionLevel указывает требуемый уровень защиты. Параметр validationHostName — это имя узла назначения удаленной сети, которое используется для проверки при обновлении до SSL. Обычно validationHostName будет тем же именем узла, которое приложение использовало для первоначального установления подключения. Если параметру protectionLevel при вызове UpgradeToSslAsyncприсвоено значение Windows.System.SocketProtectionLevel.Ssl, StreamSocket должен использовать протокол SSL/TLS для дальнейшего шифрования обмена данными по сокету. Это значение требует шифрования и никогда не позволяет использовать шифр NULL.

Обычная последовательность, используемая с методом UpgradeToSslAsync, выглядит следующим образом:

  • Создайте StreamSocket.
  • Если требуется дополнительный параметр сокета, используйте свойство StreamSocket.Control , чтобы получить экземпляр StreamSocketControl , связанный с объектом StreamSocket . Установите свойство на StreamSocketControl.
  • Если все данные должны быть отправлены и получены незашифрованными, отправьте его сейчас.
  • Вызовите метод UpgradeToSslAsync, чтобы запустить операцию обновления подключения для использования SSL/TLS.
  • Фактически согласованная сила SSL с использованием UpgradeToSslAsync может быть определена, получив свойство StreamSocketInformation.ProtectionLevel после успешного завершения асинхронной операции.

В следующем примере создается StreamSocket, выполняется попытка установить соединение с сетевой службой, отправляются некоторые исходные данные, а затем ведутся переговоры об использовании SSL/TLS. Если согласование выполнено успешно, все сетевое взаимодействие с помощью StreamSocket между клиентом и сетевым сервером будет зашифровано.

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

Создание безопасных подключений WebSocket

Как и традиционные подключения сокетов, подключения WebSocket также могут быть зашифрованы с помощью протокола TLS/SSL при использовании StreamWebSocket и MessageWebSocket функций для приложения UWP. В большинстве случаев вы хотите использовать безопасное подключение WebSocket. Это приведет к увеличению вероятности успешного подключения, так как многие прокси-серверы отклонят незашифрованные подключения WebSocket.

Примеры создания или обновления безопасного подключения сокета к сетевой службе см. в статье Как защитить подключения WebSocket с помощью TLS/SSL.

Помимо шифрования TLS/SSL, серверу может потребоваться значение заголовка Sec-WebSocket-Protocol для завершения начального рукопожатия. Это значение, представленное свойствами StreamWebSocketInformation.Protocol и свойствами MessageWebSocketInformation.Protocol, указывает версию протокола подключения и позволяет серверу правильно интерпретировать открывающее рукопожатие и обмен последующими данными. Используя эти сведения о протоколе, если в любой момент сервер не может интерпретировать входящие данные безопасным образом, подключение можно закрыть.

Если исходный запрос от клиента либо не содержит этого значения, либо предоставляет значение, которое не соответствует ожидаемому сервером, ожидаемое значение отправляется от сервера клиенту при ошибке рукопожатия WebSocket.

Аутентификация

Как предоставить аутентификационные данные при подключении по сети.

Предоставление сертификата клиента с помощью класса StreamSocket

Класс Windows.Networking.Sockets.StreamSocket поддерживает использование SSL/TLS для проверки подлинности сервера, с помощью котором приложение разговаривает. В некоторых случаях приложение также должно пройти проверку подлинности на сервере с помощью сертификата клиента TLS. В Windows 10 можно предоставить сертификат клиента в объекте StreamSocket.Control (это необходимо задать перед запуском подтверждения TLS). Если сервер запрашивает сертификат клиента, Windows будет отвечать на предоставленный сертификат.

Ниже приведен фрагмент кода, показывающий, как реализовать это:

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

Предоставление учетных данных проверки подлинности веб-службе

Сетевые API, позволяющие приложениям взаимодействовать с безопасными веб-службами, каждый предоставляет собственные методы для инициализации клиента или задания заголовка запроса с учетными данными проверки подлинности сервера и прокси-сервера. Каждый метод устанавливается с объектом PasswordCredential, указывающим имя пользователя, пароль и ресурс, для которого используются эти учетные данные. В следующей таблице представлено сопоставление этих API:

WebSockets MessageWebSocketControl.ServerCredential
MessageWebSocketControl.ProxyCredential
StreamWebSocketControl.ServerCredential
StreamWebSocketControl.ProxyCredential
Фоновая передача BackgroundDownloader.ServerCredential
BackgroundDownloader.ProxyCredential
BackgroundUploader.ServerCredential
BackgroundUploader.ProxyCredential
синдикации SyndicationClient(PasswordCredential)
SyndicationClient.ServerCredential
SyndicationClient.ProxyCredential
AtomPub AtomPubClient(PasswordCredential)
AtomPubClient.ServerCredential
AtomPubClient.ProxyCredential

Обработка сетевых исключений

В большинстве областей программирования исключение указывает на значительную проблему или сбой, вызванный некоторыми недостатками в программе. В сетевом программировании существует дополнительный источник исключений: сама сеть и характер сетевого взаимодействия. Сетевые коммуникации по сути ненадежны и подвержены неожиданному сбою. Для каждого из способов использования сети приложение должно поддерживать некоторые сведения о состоянии; и код приложения должен обрабатывать сетевые исключения, обновляя эти сведения о состоянии и инициируя соответствующую логику для повторного установления или повторения сбоев связи.

Когда универсальные приложения Windows вызывают исключение, обработчик исключений может получить более подробную информацию о причине исключения, чтобы лучше понять ошибку и принять соответствующие решения.

Каждая проекция языка поддерживает метод для получения более подробных сведений. Проекты исключений в качестве значения HRESULT в универсальных приложениях Windows. Файл Winerror.h содержит очень большой список возможных значений HRESULT, включая сетевые ошибки.

Сетевые API поддерживают различные методы получения подробных сведений о причине исключения.

  • Некоторые API предоставляют вспомогательный метод, который преобразует значение HRESULT из исключения в значение перечисления.
  • Другие API предоставляют метод для получения фактического значения HRESULT.