게임의 네트워킹Networking for games

DirectX 게임에 네트워킹 기능을 개발 하 고 통합 하는 방법에 대해 알아봅니다.Learn how to develop and incorporate networking features into your DirectX game.

한눈에 개념 보기Concepts at a glance

DirectX 게임에서 다양 한 네트워킹 기능을 사용할 수 있습니다 .이는 여러 플레이어 게임을 대규모 하는 간단한 독립 실행형 게임 인지 여부입니다.A variety of networking features can be used in your DirectX game, whether it is a simple standalone game to massively multi-player games. 네트워킹을 가장 간단 하 게 사용 하는 것은 중앙 네트워크 서버에 사용자 이름과 게임 점수를 저장 하는 것입니다.The simplest use of networking would be to store user names and game scores on a central network server.

네트워킹 Api는 인프라 (클라이언트-서버 또는 인터넷 피어 투 피어) 모델과 임시 (로컬 피어 투 피어) 게임을 사용 하는 다중 플레이어 게임에 필요 합니다.Networking APIs are needed in multi-player games that use the infrastructure (client-server or internet peer-to-peer) model and also by ad hoc (local peer-to-peer) games. 서버 기반 다중 플레이어 게임의 경우 중앙 게임 서버는 일반적으로 대부분의 게임 작업을 처리 하 고 클라이언트 게임 앱은 입력에 사용 되 고 그래픽을 표시 하 고 오디오를 재생 하는 등의 기능을 수행 합니다.For server-based multi-player games, a central game server usually handles most of the game operations and the client game app is used for input, displaying graphics, playing audio, and other features. 네트워크 전송 속도와 대기 시간은 만족 스러운 게임 환경에서 매우 중요 합니다.The speed and latency of network transfers is a concern for a satisfactory game experience.

피어 투 피어 게임의 경우 각 플레이어의 앱이 입력 및 그래픽을 처리 합니다.For peer-to-peer games, each player's app handles the input and graphics. 대부분의 경우 게임 플레이어는 네트워크 대기 시간이 더 낮아야 하지만 여전히 문제가 될 수 있도록 근접 한 위치에 있습니다.In most cases, the game players are located in close proximity so that network latency should be lower but is still a concern. 피어를 검색 하 고 연결을 설정 하는 것이 문제가 될 수 있습니다.How to discovery peers and establish a connection becomes a concern.

단일 플레이어 게임의 경우 중앙 웹 서버 또는 서비스를 사용 하 여 사용자 이름, 게임 점수 및 기타 기타 정보를 저장 하는 경우가 많습니다.For single-player games, a central Web server or service is often used to store user names, game scores, and other miscellaneous information. 이러한 게임에서는 게임 작업에 직접적인 영향을 주지 않으므로 네트워킹 전송 속도와 대기 시간이 그다지 중요 하지 않습니다.In these games, the speed and latency of networking transfers is less of a concern since it doesn't directly affect game operation.

네트워크 상태는 언제 든 지 변경 될 수 있으므로 네트워킹 Api를 사용 하는 게임에서 발생할 수 있는 네트워크 예외를 처리 해야 합니다.Network conditions can change at any time, so any game that uses networking APIs needs to handle network exceptions that may occur. 네트워크 예외 처리에 대한 자세한 내용은 네트워킹 기본 사항을 참조하세요.To learn more about handling network exceptions, see Networking basics.

방화벽과 웹 프록시는 일반적 이며 네트워킹 기능을 사용 하는 기능에 영향을 줄 수 있습니다.Firewalls and web proxies are common and can affect the ability to use networking features. 방화벽 및 프록시를 올바르게 처리 하기 위해 네트워킹을 사용 하는 게임을 준비 해야 합니다.A game that uses networking needs to be prepared to properly handle firewalls and proxies.

모바일 장치의 경우 사용 가능한 네트워크 리소스를 모니터링 하 고 로밍 또는 데이터 비용이 중요할 수 있는 요금제 네트워크에서 적절 하 게 동작 해야 합니다.For mobile devices, it is important to monitor available network resources and behave accordingly when on metered networks where roaming or data costs can be significant.

네트워크 격리는 Windows에서 사용 하는 앱 보안 모델의 일부입니다.Network isolation is part of the app security model used by Windows. Windows에서 네트워크 경계를 검색 하 고 네트워크 격리에 대 한 네트워크 액세스 제한을 적용 합니다.Windows actively discovers network boundaries and enforces network access restrictions for network isolation. 앱은 네트워크 액세스 범위를 정의 하기 위해 네트워크 격리 기능을 선언 해야 합니다.Apps must declare network isolation capabilities in order to define the scope of network access. 이러한 기능을 선언 하지 않으면 앱에서 네트워크 리소스에 액세스할 수 없습니다.Without declaring these capabilities, your app will not have access to network resources. Windows에서 앱에 대 한 네트워크 격리를 적용 하는 방법에 대 한 자세한 내용은 네트워크 격리 기능을 구성 하는 방법을 참조 하세요.To learn more about how Windows enforces network isolation for apps, see How to configure network isolation capabilities.

설계 고려 사항Design considerations

DirectX 게임에서 다양 한 네트워킹 Api를 사용할 수 있습니다.A variety of networking APIs can be used in DirectX games. 따라서 올바른 API를 선택 하는 것이 중요 합니다.So, it is important to pick the right API. Windows는 앱이 인터넷 또는 개인 네트워크를 통해 다른 컴퓨터와 장치와 통신 하는 데 사용할 수 있는 다양 한 네트워킹 Api를 지원 합니다.Windows supports a variety of networking APIs that your app can use to communicate with other computers and devices over either the Internet or private networks. 첫 번째 단계는 앱에 필요한 네트워킹 기능을 파악 하는 것입니다.Your first step is to figure out what networking features your app needs.

이러한 Api는 게임에 대해 더 인기 있는 네트워크 Api입니다.These are the more popular network APIs for games.

  • TCP 및 소켓-안정적인 연결을 제공 합니다.TCP and sockets - Provides a reliable connection. 보안이 필요 하지 않은 게임 작업에 TCP를 사용 합니다.Use TCP for game operations that don’t need security. TCP를 사용 하면 서버를 쉽게 확장할 수 있으므로 인프라 (클라이언트 서버 또는 인터넷 피어 투 피어) 모델을 사용 하는 게임에서 일반적으로 사용 됩니다.TCP allows the server to easily scale, so it is commonly used in games that use the infrastructure (client-server or internet peer-to-peer) model. TCP는 Wi-fi Direct 및 Bluetooth를 통해 임시 (로컬 피어 투 피어) 게임에서 사용할 수도 있습니다.TCP can also be used by ad hoc (local peer-to-peer) games over Wi-Fi Direct and Bluetooth. TCP는 게임 개체 이동, 문자 상호 작용, 텍스트 채팅 및 기타 작업에 일반적으로 사용 됩니다.TCP is commonly used for game object movement, character interaction, text chat, and other operations. Streamsocket 클래스는 Microsoft Store 게임에서 사용할 수 있는 TCP 소켓을 제공 합니다.The StreamSocket class provides a TCP socket that can be used in Microsoft Store games. Streamsocket 클래스는 Windows:: 네트워킹:: Sockets 네임 스페이스의 관련 클래스와 함께 사용 됩니다.The StreamSocket class is used with related classes in the Windows::Networking::Sockets namespace.
  • SSL을 사용 하는 TCP 및 소켓-도청을 방지 하는 안정적인 연결을 제공 합니다.TCP and sockets using SSL - Provides a reliable connection that prevents eavesdropping. 보안이 필요한 게임 작업에 SSL과 함께 TCP 연결을 사용 합니다.Use TCP connections with SSL for game operations that need security. SSL의 암호화 및 오버 헤드로 인해 대기 시간 및 성능에 비용이 추가 되므로 보안이 필요한 경우에만 사용 됩니다.The encryption and overhead of SSL adds a cost in latency and performance, so it is only used when security is needed. TCP with SSL은 일반적으로 로그인, 구매 및 거래 자산, 게임 문자 생성 및 관리에 사용 됩니다.TCP with SSL is commonly used for login, purchasing and trading assets, game character creation and management. Streamsocket 클래스는 SSL을 지 원하는 TCP 소켓을 제공 합니다.The StreamSocket class provides a TCP socket that supports SSL.
  • UDP 및 소켓-오버 헤드가 낮은 불안정 한 네트워크 전송을 제공 합니다.UDP and sockets - Provides unreliable network transfers with low overhead. UDP는 짧은 대기 시간을 필요로 하 고 일부 패킷 손실을 허용할 수 있는 게임 작업에 사용 됩니다.UDP is used for game operations that require low latency and can tolerate some packet loss. 게임, 촬영 및 tracers, 네트워크 오디오, 음성 채팅 등을 방지 하는 데 주로 사용 됩니다.This is often used for fighting games, shooting and tracers, network audio, and voice chat. DatagramSocket 클래스는 Microsoft Store 게임에서 사용할 수 있는 UDP 소켓을 제공 합니다.The DatagramSocket class provides a UDP socket that can be used in Microsoft Store games. DatagramSocket 클래스는 Windows:: 네트워킹:: Sockets 네임 스페이스의 관련 클래스와 함께 사용 됩니다.The DatagramSocket class is used with related classes in the Windows::Networking::Sockets namespace.
  • HTTP 클라이언트-HTTP 서버에 대 한 신뢰할 수 있는 연결을 제공 합니다.HTTP Client - Provides a reliable connection to HTTP servers. 가장 일반적인 네트워킹 시나리오는 웹 사이트에 액세스 하 여 정보를 검색 하거나 저장 하는 것입니다.The most common networking scenario is to access a web site to retrieve or store information. 간단한 예로 사용자 정보 및 게임 점수를 저장 하는 웹 사이트를 사용 하는 게임이 있습니다.A simple example would be a game that uses a website to store user information and game scores. SSL과 함께 보안을 사용 하는 경우 HTTP 클라이언트를 로그인, 구매, 거래 자산, 게임 문자 생성 및 관리에 사용할 수 있습니다.When used with SSL for security, an HTTP client can be used for login, purchasing, trading assets, game character creation, and management. Httpclient 클래스는 Microsoft Store 게임에서 사용할 최신 HTTP 클라이언트 API를 제공 합니다.The HttpClient class provides a modern HTTP client API for use in Microsoft Store games. Httpclient 클래스는 Windows:: Web:: Http 네임 스페이스의 관련 클래스와 함께 사용 됩니다.The HttpClient class is used with related classes in the Windows::Web::Http namespace.

DirectX 게임에서 네트워크 예외 처리Handling network exceptions in your DirectX game

DirectX 게임에서 네트워크 예외가 발생 하는 경우이는 심각한 문제나 실패를 나타냅니다.When a network exception occurs in your DirectX game, this indicates a significant problem or failure. 네트워킹 Api를 사용 하는 경우 여러 가지 이유로 예외가 발생할 수 있습니다.Exceptions can occur for many reasons when using networking APIs. 네트워크 연결이 변경 되거나 원격 호스트나 서버와 관련 된 다른 네트워킹 문제가 발생 하는 경우가 종종 있습니다.Often, the exception can result from changes in network connectivity or other networking issues with the remote host or server.

네트워킹 Api를 사용할 때 예외가 발생 하는 원인은 다음과 같습니다.Some causes of exceptions when using networking APIs include the following:

  • 호스트 이름 또는 URI에 대 한 사용자 입력에 오류가 있으며 잘못 되었습니다.Input from the user for a hostname or a URI contains errors and is not valid.
  • 호스트 이름 또는 URi를 조회할 때 이름 확인 실패Name resolutions failures when looking up a hostname or a URi.
  • 네트워크 연결의 손실 또는 변경Loss or change in network connectivity.
  • 소켓이 나 HTTP 클라이언트 Api를 사용 하 여 네트워크 연결에 실패 했습니다.Network connection failures using sockets or the HTTP client APIs.
  • 네트워크 서버 또는 원격 끝점 오류입니다.Network server or remote endpoint errors.
  • 기타 네트워킹 오류입니다.Miscellaneous networking errors.

네트워크 오류의 예외 (예: 연결 손실 또는 변경, 연결 실패 및 서버 오류)는 언제 든 지 발생할 수 있습니다.Exceptions from network errors (for example, loss or change of connectivity, connection failures, and server failures) can happen at any time. 이러한 오류가 발생 하면 예외가 throw 됩니다.These errors result in exceptions being thrown. 응용 프로그램에서 예외를 처리 하지 않으면 런타임에 의해 전체 앱이 종료 될 수 있습니다.If an exception is not handled by your app, it can cause your entire app to be terminated by the runtime.

대부분의 비동기 네트워크 메서드를 호출할 때 예외를 처리 하는 코드를 작성 해야 합니다.You must write code to handle exceptions when you call most asynchronous network methods. 경우에 따라 예외가 발생 하면 문제를 해결 하는 방법으로 네트워크 메서드를 다시 시도할 수 있습니다.Sometimes, when an exception occurs, a network method can be retried as a way to resolve the problem. 다른 경우에는 이전에 캐시 된 데이터를 사용 하 여 네트워크 연결 없이 앱이 계속 진행 되도록 계획 해야 할 수도 있습니다.Other times, your app may need to plan to continue without network connectivity using previously cached data.

UWP (유니버설 Windows 플랫폼) 앱은 일반적으로 단일 예외를 throw 합니다.Universal Windows Platform (UWP) apps generally throw a single exception. 예외 처리기는 예외 원인에 대 한 자세한 정보를 검색 하 여 오류를 보다 잘 이해 하 고 적절 한 결정을 내릴 수 있습니다.Your exception handler can retrieve more detailed information about the cause of the exception to better understand the failure and make appropriate decisions.

UWP 앱 인 DirectX 게임에서 예외가 발생 하면 오류의 원인에 대 한 HRESULT 값을 검색할 수 있습니다.When an exception occurs in a DirectX game that is a UWP app, the HRESULT value for the cause of the error can be retrieved. Winerror.h 포함 파일에는 네트워크 오류가 포함 된 가능한 HRESULT 값의 많은 목록이 포함 되어 있습니다.The Winerror.h include file contains a large list of possible HRESULT values that includes network errors.

네트워킹 Api는 예외의 원인에 대 한 자세한 정보를 검색 하는 다양 한 방법을 지원 합니다.The networking APIs support different methods for retrieving this detailed information about the cause of an exception.

  • 예외를 발생 시킨 오류의 HRESULT 값을 검색 하는 메서드입니다.A method to retrieve the HRESULT value of the error that caused the exception. 잠재적 HRESULT 값의 가능한 목록은 크고 지정 되지 않습니다.The possible list of potential HRESULT values is large and unspecified. 네트워킹 Api를 사용 하는 경우 HRESULT 값을 검색할 수 있습니다.The HRESULT value can be retrieved when using any of the networking APIs.
  • HRESULT 값을 열거형 값으로 변환 하는 도우미 메서드입니다.A helper method that converts the HRESULT value to an enumeration value. 가능한 열거형 값 목록이 지정 되 고 상대적으로 작습니다.The list of possible enumeration values is specified and relatively small. 도우미 메서드는 Windows:: 네트워킹:: Sockets의 소켓 클래스에 사용할 수 있습니다.A helper method is available for the socket classes in the Windows::Networking::Sockets.

Windows의 예외Exceptions in Windows.Networking.Sockets

소켓에 사용 되는 호스트 이름 클래스의 생성자는 전달 된 문자열이 유효한 호스트 이름이 아닌 경우 예외를 throw 할 수 있습니다 (호스트 이름에 허용 되지 않는 문자 포함).The constructor for the HostName class used with sockets can throw an exception if the string passed is not a valid hostname (contains characters that are not allowed in a host name). 앱에서 게임에 대 한 피어 연결에 대 한 호스트 이름 에 대 한 사용자의 입력을 가져오는 경우 생성자는 try/catch 블록에 있어야 합니다.If an app gets input from the user for the HostName for a peer connection for gaming, the constructor should be in a try/catch block. 예외가 throw 되 면 앱에서 사용자에 게 알리고 새 호스트 이름을 요청할 수 있습니다.If an exception is thrown, the app can notify the user and request a new hostname.

사용자의 호스트 이름에 대 한 문자열의 유효성을 검사 하는 코드를 추가 합니다.Add code to validate a string for a hostname from the user

// Define some variables at the class level.
Windows::Networking::HostName^ remoteHost;

bool isHostnameFromUser = false;
bool isHostnameValid = false;

///...

// If the value of 'remoteHostname' is set by the user in a control as input 
// and is therefore untrusted input and could contain errors. 
// If we can't create a valid hostname, we notify the user in statusText 
// about the incorrect input.

String ^hostString = remoteHostname;

try 
{
    remoteHost = ref new Windows::Networking:Host(hostString);
    isHostnameValid = true;
}
catch (InvalidArgumentException ^ex)
{
    statusText->Text = "You entered a bad hostname, please re-enter a valid hostname.";
    return;
}

isHostnameFromUser = true;

// ... Continue with code to execute with a valid hostname.

Windows. 네트워킹과 네임 스페이스에는 소켓을 사용할 때 오류를 처리 하기 위한 편리한 도우미 메서드 및 열거가 있습니다.The Windows.Networking.Sockets namespace has convenient helper methods and enumerations for handling errors when using sockets. 이는 앱에서 특정 네트워크 예외를 다르게 처리 하는 데 유용할 수 있습니다.This can be useful for handling specific network exceptions differently in your app.

DatagramSocket, Streamsocket또는 StreamSocketListener 작업에서 오류가 발생 하면 예외가 throw 됩니다.An error encountered on DatagramSocket, StreamSocket, or StreamSocketListener operation results in an exception being thrown. 예외의 원인은 HRESULT 값으로 표시 되는 오류 값입니다.The cause of the exception is an error value represented as an HRESULT value. GetStatus 메서드는 소켓 작업에서 SocketErrorStatus 열거형 값으로 네트워크 오류를 변환 하는 데 사용 됩니다.The SocketError.GetStatus method is used to convert a network error from a socket operation to a SocketErrorStatus enumeration value. 대부분의 SocketErrorStatus 열거형 값은 네이티브 Windows 소켓 작업에서 반환 되는 오류에 해당 합니다.Most of the SocketErrorStatus enumeration values correspond to an error returned by the native Windows sockets operation. 앱은 특정 SocketErrorStatus 열거 값을 필터링 하 여 예외의 원인에 따라 앱 동작을 수정할 수 있습니다.An app can filter on specific SocketErrorStatus enumeration values to modify app behavior depending on the cause of the exception.

매개 변수 유효성 검사 오류의 경우 응용 프로그램은 예외의 HRESULT 를 사용 하 여 예외를 발생 시킨 오류에 대 한 자세한 정보를 확인할 수도 있습니다.For parameter validation errors, an app can also use the HRESULT from the exception to learn more detailed information about the error that caused the exception. 가능한 HRESULT 값은 winerror.h 헤더 파일에 나와 있습니다.Possible HRESULT values are listed in the Winerror.h header file. 대부분의 매개 변수 유효성 검사 오류에 대해 반환 되는 HRESULTE _ invalidarg입니다.For most parameter validation errors, the HRESULT returned is E_INVALIDARG.

스트림 소켓 연결을 시도할 때 예외를 처리 하는 코드를 추가 합니다.Add code to handle exceptions when trying to make a stream socket connection

using namespace Windows::Networking;
using namespace Windows::Networking::Sockets;
    
    // Define some more variables at the class level.

    bool isSocketConnected = false
    bool retrySocketConnect = false;

    // The number of times we have tried to connect the socket.
    unsigned int retryConnectCount = 0;

    // The maximum number of times to retry a connect operation.
    unsigned int maxRetryConnectCount = 5; 
    ///...

    // We pass in a valid remoteHost and serviceName parameter.
    // The hostname can contain a name or an IP address.
    // The servicename can contain a string or a TCP port number.

    StreamSocket ^ socket = ref new StreamSocket();
    SocketErrorStatus errorStatus; 
    HResult hr;

    // Save the socket, so any subsequent steps can use it.
    CoreApplication::Properties->Insert("clientSocket", socket);

    // Connect to the remote server. 
    create_task(socket->ConnectAsync(
            remoteHost,
            serviceName,
            SocketProtectionLevel::PlainSocket)).then([this] (task<void> previousTask)
    {
        try
        {
            // Try getting all exceptions from the continuation chain above this point.
            previousTask.get();

            isSocketConnected = true;
            // Mark the socket as connected. We do not really care about the value of the property, but the mere 
            // existence of  it means that we are connected.
            CoreApplication::Properties->Insert("connected", nullptr);
        }
        catch (Exception^ ex)
        {
            hr = ex.HResult;
            errorStatus = SocketStatus::GetStatus(hr); 
            if (errorStatus != Unknown)
            {
                                                                switch (errorStatus) 
                   {
                    case HostNotFound:
                        // If the hostname is from the user, this may indicate a bad input.
                        // Set a flag to ask the user to re-enter the hostname.
                        isHostnameValid = false;
                        return;
                        break;
                    case ConnectionRefused:
                        // The server might be temporarily busy.
                        retrySocketConnect = true;
                        return;
                        break; 
                    case NetworkIsUnreachable: 
                        // This could be a connectivity issue.
                        retrySocketConnect = true;
                        break;
                    case UnreachableHost: 
                        // This could be a connectivity issue.
                        retrySocketConnect = true;
                        break;
                    case NetworkIsDown: 
                        // This could be a connectivity issue.
                        retrySocketConnect = true;
                        break;
                    // Handle other errors. 
                    default: 
                        // The connection failed and no options are available.
                        // Try to use cached data if it is available. 
                        // You may want to tell the user that the connect failed.
                        break;
                }
                }
                else 
                {
                    // Received an Hresult that is not mapped to an enum.
                    // This could be a connectivity issue.
                    retrySocketConnect = true;
                }
            }
        });
    }

Windows의 예외Exceptions in Windows.Web.Http

Windows:: Web:: Http:: HttpClient 에 사용 되는 Windows:: Foundation:: uri 클래스의 생성자는 전달 된 문자열이 유효한 uri가 아닌 경우 (Uri에서 허용 되지 않는 문자 포함) 예외를 throw 할 수 있습니다.The constructor for the Windows::Foundation::Uri class used with Windows::Web::Http::HttpClient can throw an exception if the string passed is not a valid URI (contains characters that are not allowed in a URI). C + +에서는 URI에 대 한 문자열을 시도 하 고 구문 분석할 수 있는 메서드가 없습니다.In C++, there is no method to try and parse a string to a URI. 앱이 Windows:: Foundation:: Uri에 대 한 사용자의 입력을 가져오는 경우 생성자는 try/catch 블록에 있어야 합니다.If an app gets input from the user for the Windows::Foundation::Uri, the constructor should be in a try/catch block. 예외가 throw 되 면 앱에서 사용자에 게 알리고 새 URI를 요청할 수 있습니다.If an exception is thrown, the app can notify the user and request a new URI.

또한 응용 프로그램은 URI의 체계가 HTTP 또는 HTTPS 인지 확인 해야 합니다 .이는 Windows:: Web:: HTTP:: HttpClient에서 지원 되는 유일한 체계 이기 때문입니다.Your app should also check that the scheme in the URI is HTTP or HTTPS since these are the only schemes supported by the Windows::Web::Http::HttpClient.

사용자의 URI에 대 한 문자열의 유효성을 검사 하는 코드를 추가 합니다.Add code to validate a string for a URI from the user

    // Define some variables at the class level.
    Windows::Foundation::Uri^ resourceUri;

    bool isUriFromUser = false;
    bool isUriValid = false;

    ///...

    // If the value of 'inputUri' is set by the user in a control as input 
    // and is therefore untrusted input and could contain errors. 
    // If we can't create a valid hostname, we notify the user in statusText 
    // about the incorrect input.

    String ^uriString = inputUri;

    try 
    {
        isUriValid = false;
        resourceUri = ref new Windows::Foundation:Uri(uriString);

        if (resourceUri->SchemeName != "http" && resourceUri->SchemeName != "https")
        {
            statusText->Text = "Only 'http' and 'https' schemes supported. Please re-enter URI";
            return;
        }
        isUriValid = true;
    }
    catch (InvalidArgumentException ^ex)
    {
        statusText->Text = "You entered a bad URI, please re-enter Uri to continue.";
        return;
    }

    isUriFromUser = true;


    // ... Continue with code to execute with a valid URI.

Windows:: Web:: Http 네임 스페이스에는 편리한 함수가 없습니다.The Windows::Web::Http namespace lacks a convenience function. 따라서 Httpclient 및이 네임 스페이스의 다른 클래스를 사용 하는 앱은 HRESULT 값을 사용 해야 합니다.So, an app using HttpClient and other classes in this namespace needs to use the HRESULT value.

C + +를 사용 하는 앱에서 Platform:: exception 은 예외가 발생할 때 앱을 실행 하는 동안 오류를 나타냅니다.In apps using C++, the Platform::Exception represents an error during app execution when an exception occurs. Platform:: Exception:: HResult 속성은 특정 예외에 할당 된 HResult 를 반환 합니다.The Platform::Exception::HResult property returns the HRESULT assigned to the specific exception. Platform:: Exception:: Message 속성은 HRESULT 값과 연결 된 시스템 제공 문자열을 반환 합니다.The Platform::Exception::Message property returns the system-provided string that is associated with the HRESULT value. 가능한 HRESULT 값은 winerror.h 헤더 파일에 나와 있습니다.Possible HRESULT values are listed in the Winerror.h header file. 앱은 예외의 원인에 따라 앱 동작을 수정 하는 특정 HRESULT 값을 기준으로 필터링 할 수 있습니다.An app can filter on specific HRESULT values to modify app behavior depending on the cause of the exception.

대부분의 매개 변수 유효성 검사 오류에 대해 반환 되는 HRESULTE _ invalidarg입니다.For most parameter validation errors, the HRESULT returned is E_INVALIDARG. 일부 잘못된 메서드 호출의 경우 반환되는 HRESULTE_ILLEGAL_METHOD_CALL입니다.For some illegal method calls, the HRESULT returned is E_ILLEGAL_METHOD_CALL.

Httpclient 를 사용 하 여 HTTP 서버에 연결 하려고 할 때 예외를 처리 하는 코드를 추가 합니다.Add code to handle exceptions when trying to use HttpClient to connect to an HTTP server

using namespace Windows::Foundation;
using namespace Windows::Web::Http;
    
    // Define some more variables at the class level.

    bool isHttpClientConnected = false
    bool retryHttpClient = false;

    // The number of times we have tried to connect the socket
    unsigned int retryConnectCount = 0;

    // The maximum number of times to retry a connect operation.
    unsigned int maxRetryConnectCount = 5; 
    ///...

    // We pass in a valid resourceUri parameter.
    // The URI must contain a scheme and a name or an IP address.

    HttpClient ^ httpClient = ref new HttpClient();
    HResult hr;

    // Save the httpClient, so any subsequent steps can use it.
    CoreApplication::Properties->Insert("httpClient", httpClient);

    // Send a GET request to the HTTP server. 
    create_task(httpClient->GetAsync(resourceUri)).then([this] (task<void> previousTask)
    {
        try
        {
            // Try getting all exceptions from the continuation chain above this point.
            previousTask.get();

            isHttpClientConnected = true;
            // Mark the HttClient as connected. We do not really care about the value of the property, but the mere 
            // existence of  it means that we are connected.
            CoreApplication::Properties->Insert("connected", nullptr);
        }
        catch (Exception^ ex)
        {
            hr = ex.HResult;
                                                switch (errorStatus) 
               {
                case WININET_E_NAME_NOT_RESOLVED:
                    // If the Uri is from the user, this may indicate a bad input.
                    // Set a flag to ask user to re-enter the Uri.
                    isUriValid = false;
                    return;
                    break;
                case WININET_E_CANNOT_CONNECT:
                    // The server might be temporarily busy.
                    retryHttpClientConnect = true;
                    return;
                    break; 
                case WININET_E_CONNECTION_ABORTED: 
                    // This could be a connectivity issue.
                    retryHttpClientConnect = true;
                    break;
                case WININET_E_CONNECTION_RESET: 
                    // This could be a connectivity issue.
                    retryHttpClientConnect = true;
                    break;
                case INET_E_RESOURCE_NOT_FOUND: 
                    // The server cannot locate the resource specified in the uri.
                    // If the Uri is from user, this may indicate a bad input.
                    // Set a flag to ask the user to re-enter the Uri
                    isUriValid = false;
                    return;
                    break;
                // Handle other errors. 
                default: 
                    // The connection failed and no options are available.
                    // Try to use cached data if it is available. 
                    // You may want to tell the user that the connect failed.
                    break;
            }
            else 
            {
                // Received an Hresult that is not mapped to an enum.
                // This could be a connectivity issue.
                retrySocketConnect = true;
            }
        }
    });

기타 리소스Other resources

참조Reference

방법Sample apps