セットアップ
このセクションでは、Winsock API を使用する際にインクルードする必要がある .h および .lib ファイルについて説明します。- ソース ファイルに
#include <winhttp.h>を追加します。 - PC タイトルの場合、引き続き
Winhttp.libをリンクします。 - XBOX コンソール タイトルの場合、
Winhttp.libに直接リンクする代わりに、XGamePlatform.libをリンクする必要があります。
WINAPI_PARTITION_GAMES API ファミリの API のみが、Microsoft Game Development Kit (GDK) タイトルで動作します。
ネットワーク初期化
WSAStartup への最初の呼び出しの前に、Microsoft Game Development Kit (GDK) タイトルはネットワーク スタックが準備完了であることを確認する必要があります。タイトルの起動プロセスの早い段階でWSAStartup が呼び出されると、WSAStartup またはその後の Winsock 呼び出しが失敗する可能性があります。ネットワーク スタックが準備完了であるかどうかを判断する方法の詳細については、ネットワークの初期化と接続 を参照してください。
サスペンドと再開
RegisterAppStateChangeNotification を介してサスペンドおよび再開イベントを登録する必要があります。サスペンド時には、すべてのソケット ハンドルを閉じ、WSACleanup を呼び出す必要があります。再開時には、WSAStartup を呼び出して新しいソケットを作成する前に、再度 ネットワーク初期化 を待つ必要があります。
Microsoft Game Development Kit (GDK) 優先ローカル User Datagram Protocol (UDP) マルチプレイヤー ポート API
Microsoft Game Development Kit (GDK) の 優先ローカル UDP マルチプレイヤー ポート API は、UDP 経由でゲーム内通信を容易にするために、タイトルが Winsock を使用して bind する最適で動的に選択されたポートを返します。Microsoft Game Development Kit (GDK) プラットフォームは、この特定のポートが各ユーザーのネットワーク環境で動作する可能性が最も高いポートであることを保証します。この特定のポートを使用することで、プラットフォームのカスタマー サポートおよび診断フローの活用が最大化され、標準化されたネットワーク アドレス変換 (NAT) の互換性が向上し、標準化された UPnP™ 認定デバイスの機能が提供され、Quality of Service (QoS) ルーターおよび ISP のアルゴリズムに対してパケットがリアルタイム センシティブとして識別されます。 UDP ポートは、ピアツーピア ネットワーク トポロジに依存するタイトルに特に関連します。これは、ファイアウォール パンチングを実行せずにファイアウォールを通じて受信 UDP パケットを許可する唯一のポートです。Microsoft Game Development Kit (GDK) のピアツーピア ネットワーク トポロジに依存するタイトルは、依然として、独自のパブリック IP アドレスとポートの検出、および Moderate または Strict NAT タイプを持つクライアント向けの NAT パンチング ソリューションを提供することが期待されます。優先ポート単独では、これらの技術の成功率を向上させますが、それらの代替となるものではありません。 クライアント/サーバー ネットワーク トポロジを使用するタイトルも UDP ポートを使用することでメリットを得られます。病院、ホテル、大学の寮などで一般的なキャプティブ ポータルやその他のソース ベースのフィルタリング アプローチにおいて、トラブルシューティング、UPnP™、およびパケット識別は依然として重要です。 Microsoft Game Development Kit (GDK) タイトルには、メインのマルチプレイヤーおよびチャットのネットワーク トラフィックに優先ローカル UDP マルチプレイヤー ポートを使用することを強くお勧めします。ソケットのセキュリティ
Microsoft Game Development Kit (GDK) タイトルは、Winsock API を使用してネットワーク経由で転送されるすべてのデータに対して、適切なセキュリティと暗号化があることを保証する責任があります。 BCrypt、WinCrypt、schannel、およびその他の標準的な Windows API は、推奨される暗号プリミティブを提供します。Microsoft Game Development Kit (GDK) タイトルは、これらの API を使用して、すべてのソケット フローに対して Datagram Transport Layer Security (DTLS) およびその他の標準化されたセキュリティ プロトコルを実装する必要があります。 独自のセキュリティ モデルを実装したくないタイトルの場合、Microsoft Game Development Kit (GDK) ライブラリの PlayFab Party は、その他の機能とともに、完全で統合されたソケット セキュリティの仕組みを提供します。ソケット メモリに関する考慮事項
Microsoft Game Development Kit (GDK) タイトルは現在、すべての WinSock および WinHTTP の使用に対してネットワーク スタックに約 16MB しか利用できません。それを超えるとシステムが不安定になる可能性があります。メモリ消費の最大のソースの 1 つは、WinSock のカーネル モードの送信および受信メモリ プールで、ここで着信および発信パケットが、ネットワーク経由で送信されるか、多くのrecv バリアントの 1 つを通してタイトルのユーザー モード メモリに転送されるまで格納されます。
特に高帯域幅の状況では、リモート ピアやサーバーがプッシュする速度と少なくとも同等の速度で、低レイテンシで独自のユーザー モード バッファーにデータを転送する責任がタイトルにあります。これを行うには、複雑さと保証が徐々に増していくいくつかの方法がありますが、以下のすべての提案の根底にある目標は、データが到着したらすぐに転送するためのユーザー モード バッファーを常に保留状態にすることで、カーネルがメモリを増加させて割り当てる必要がないようにすることです。実質的な効果としては、保留中の未処理のデータのメモリ使用量を、極めて限られたカーネル プールから、はるかに大きなタイトル メモリ プール内で自ら直接管理するメモリに変更することです。
WinSock を使用する高レベル API には通常、そのソケットのカーネル メモリ使用量を制御するメカニズムがあります。WinHTTP と XCurl はどちらも、それぞれの読み取り通知メカニズムを通じてカーネル メモリ使用量の制御を提供します。一方、XSAPI や PlayFab Party などの他の API は、以下の技術を使用してカーネル メモリ使用量を最小化しています。
Berkeley (BSD) ソケット
ブロッキングの Berkeley ソケット API を使い続けたい場合、recv 呼び出しの頻度を増やす必要があります。受信データを別の場所で処理するためにキューに入れる、タイトなループを持つ専用スレッドの使用をお勧めします。理想的には、スレッドは常に recv 呼び出しの内部でブロックされている必要があります。recv 呼び出しの外部で費やされた時間は、再度 recv を呼び出すのを待つ間にカーネル メモリ使用量が増加する可能性のある時間となります。多くの場合、再度 recv を呼び出す前にデータを処理しようとすると、タイトルが遅れ、データが高い速度で受信され続ける限りカーネル メモリ使用量が増加します。また、カーネル バッファー サイズの境界に合わせ、ジッターやバースト的な送信パターンに対応するために、少なくとも 8k のバッファー サイズを指定することをお勧めします。WinSock の重ね合わせ I/O
WinSock の重ね合わせ I/O を使用すると、ユーザー モードの受信バッファーを非同期に保留状態のままにできます。また、これによりカーネルがメモリ バッファーを直接使用できるようになり、追加のメモリ コピー (Berkeley ソケット パラダイムとは異なり) を回避できます。バッファーが常に保留状態であると仮定すると、カーネルは受信データに対してまったく割り当てを行いません。さらに、重ね合わせ I/O では、SO_RCVBUF と SO_SNDBUF に特別な値 0 を設定でき、これにより送信/受信カーネル メモリの割り当てをほぼ完全に回避できます。 このアプローチは、ほとんどのシナリオでソケットが使用するメモリを管理する最良の方法です。Registered I/O
Registered I/O は複雑なネットワーク API で、最も低いレイテンシを提供し、送受信操作にカーネル メモリが使用されないことを保証します。カーネルによって直接使用される複数の受信/送信バッファーをセットアップして、着信データ用のバッファーが常に準備できるようにできます。最大 UDP 転送単位サイズ
Microsoft Game Development Kit (GDK) には理論上の最大ペイロード サイズが存在しますが、実際には、特定の接続の最大値はネットワーク接続タイプによって異なります。タイトルの実行中に変化することもあります。実際の最大転送単位 (MTU) を判断してタイトルの実行中の MTU の変更に反応しようとするのではなく、パケットあたりの最大 UDP ペイロードを 1,384 バイトと想定してネットワーク コードを設計する必要があります。この値は、すべてのネットワーク構成において、伝送中の断片化を回避するために安全に使用できます。ソケット タイプが IPv4 か IPv6 かに関係なく、これをお勧めします。 1,384 バイトを超えるペイロードの伝送には、多くの場合 IP レベルのパケット断片化が必要です。IP パケット断片化は、ISP やユーザーのホーム ルーターおよびデバイスにあまりよくサポートされていません。これらのネットワーク構成では、IP パケット断片化は Winsock API からの障害を引き起こしません。断片化はタイトルにはパケット損失として現れます。IP レベルのパケット断片化を回避するには、パケット ペイロードの安全な最大値として 1,384 バイトを使用してください。 タイトルが断片化を回避するようにし、マルチプレイヤー ネットワークの最低要件に関する関連する XBOX Requirements を満たすのを支援するために、タイトルが開くすべてのソケットにIP_DONTFRAGMENT と IP_USER_MTU ソケット オプションを適用する必要があります。これらのフラグは、XGameRuntimeIsFeatureAvailable(XGameRuntimeFeature::XNetworking) API が true を返す場合にのみ、Microsoft Game Development Kit (GDK) タイトルで使用できます。XNetworking 機能が利用できない場合、setsockopt 呼び出しは失敗します。次は、これら 2 つのソケット オプションを設定する方法の例です。
