ソケットの詳細制御の使い方 (HTML)
[ この記事は、Windows ランタイム アプリを作成する Windows 8.x および Windows Phone 8.x 開発者を対象としています。Windows 10 向けの開発を行っている場合は、「最新のドキュメント」をご覧ください]
このトピックでは、Windows ストア アプリで DatagramSocket、StreamSocket、StreamSocketListener の 3 つの機能を使うときに、ソケットの詳細制御を使う方法について説明します。
理解しておく必要があること
テクノロジ
-
ソケットと WebSocket を使ったネットワーク通信を可能にします。
必要条件
- このトピックのコード例は、JavaScript で記述されています。ソケットについての基本的な理解があることが条件となります。
詳細制御の概要
DatagramSocket、StreamSocket、StreamSocketListener のクラスにはいずれも、詳細な制御の扱いに関して同じモデルが採用されています。これらの主要なクラスにはそれぞれ、詳細な制御を行うための関連クラスが存在し、相互にやり取りしています。
- DatagramSocketControl: DatagramSocket オブジェクトに対するソケット制御データを提供します。
- StreamSocketControl: StreamSocket オブジェクトに対するソケット制御データを提供します。
- StreamSocketListenerControl: StreamSocketListener オブジェクトに対するソケット制御データを提供します。
3 つのどのクラスでも、詳細な制御を行うための基本的なモデルは同じです。 以降の説明では StreamSocket を例として使っていますが、同じ手順を DatagramSocket や StreamSocketListener にも適用できます。
- StreamSocket を作成します。
- StreamSocket.Control プロパティを使って、StreamSocket オブジェクトに関連付けられている StreamSocketControl インスタンスを取得します。
- StreamSocketControl のプロパティを取得または設定して詳細なソケット オプションを設定します。
接続操作やソケットをバインドする操作をアプリから行うときは、必ず StreamSocketControl のプロパティを先に設定しておく必要があります。このため、詳細オプションを設定するタイミングはソケットの作成直後をお勧めします。ソケットからいずれかの ConnectAsync メソッドが呼び出された後に StreamSocketControl プロパティを設定することは避けてください。
データグラム ソケットの制御
DatagramSocket は、UDP データグラム ソケットを使ったネットワーク通信をサポートします。 DatagramSocket の詳細オプションは 1 つだけです。
- DatagramSocketControl.QualityOfService: DatagramSocket オブジェクトのサービスの品質を示します。
このサービスの品質は、DatagramSocket オブジェクトでパケットを受信するスレッドの優先順位に影響します。サービスの品質には、SocketQualityOfService 列挙の 2 つの値のいずれかを設定できます。 DatagramSocket が作成される際の既定の設定は normal です。 lowLatency に設定すると、パケットを受信するスレッドの優先順位が高くなります。通常、このオプションを使うのは、オーディオ アプリのようなタイミングが非常に重要なアプリだけです。
次の例では、DatagramSocket を作成し、タイミングが重要なアプリの DatagramSocketControl.QualityOfService を lowLatency に設定します。その後は、DatagramSocket に用意されている他のメソッドを使って、ソケットをバインドしたりソケットに接続したりできます。
var clientSocket = new Windows.Networking.Sockets.DatagramSocket();
// The control object is associated with the socket
// Get the current setting for quality of service
// This isn't needed, but it shows how to get the current setting
var currentSetting = clientSocket.Control.QualityOfService;
// Set quality of service to low latency
clientSocket.Control.QualityOfService = SocketQualityOfService.LowLatency;
// Now use the DatagramSocket to call:
// BindEndpointAsync, BindServiceNameAsync,
// ConnectAsync, GetOutputstreamAsync, or
// JoinMulticastGroup
StreamSocket ソケットの制御
StreamSocket は、TCP ストリーム ソケットを使ったネットワーク通信をサポートします。 StreamSocket には、いくつかの詳細オプションが存在します。
- StreamSocketControl.KeepAlive: StreamSocket オブジェクトでリモートの配信先にキープアライブ パケットを送信するかどうかを示します。
- StreamSocketControl.NoDelay: StreamSocket オブジェクトで Nagle アルゴリズムを使うかどうかを示します。
- StreamSocketControl.OutboundBufferSizeInBytes: StreamSocket オブジェクトでデータを送るときの送信バッファーのサイズ (バイト単位) を制御します。
- StreamSocketControl.QualityOfService: StreamSocket オブジェクトのサービスの品質を示します。
ここでは、Nagle アルゴリズムを有効にするかどうかを制御する StreamSocketControl.NoDelay プロパティを変更します。
Nagle アルゴリズムは、ネットワークを介して送信する必要があるパケットの数を減らして TCP/IP ネットワークの効率を高める手法です。 このアルゴリズムは、データを小さいチャンクに分けて繰り返し発信するアプリで生じる問題に対処する場合に使います。他にヘッダー オプションを持たない IPv4 の TCP パケットには、40 バイト (IP と TCP で 20 バイトずつ) のヘッダーがあります。そのため、アプリから送信するパケットは 4 バイトだけでも、パケット データのオーバーヘッドは非常に大きくなります。 これが問題になるのは、ほとんどのキー操作で 1 ~ 2 バイトの小さいデータが生成されてすぐに送信されるリモート アクセス プロトコル (Telnet や Secure Shell など) の場合です。低速なリンクの場合、それらのパケットの多くがネットワーク上で同時に転送される可能性があります。Nagle アルゴリズムでは、多数の小さい送信メッセージを結合し、それらをまとめて送信します。送信元は、配信通知を受け取っていない送信パケットがあると、出力するすべてのパケットが揃うまで出力をバッファーに保持します。これにより、出力をすべてまとめて送信することができます。Nagle アルゴリズムを適用すると、待ち時間が増える代わりに帯域幅を増やす効果があります。送信のバッファー処理を内部で行うように設計したアプリでは、Nagle アルゴリズムを使う必要はありません。
StreamSocket の作成時点の既定の設定では、このオプションは true に設定され、Nagle アルゴリズムが無効になっています。この設定の場合、小さいメッセージを送信する際に待ち時間が発生する可能性は少なくなります。ただし、小さいパケットを大量に送信するアプリで StreamSocket を使う場合は、待ち時間さえ問題にならなければ、Nagle アルゴリズムを有効にして効率を高めることができます。
次の例では、StreamSocket を作り、StreamSocketControl.NoDelay を false に設定します。その後は、StreamSocket に用意されている他のメソッドを使ってソケットに接続することができます。
var clientSocket = new Windows.Networking.Sockets.StreamSocket();
// The control object is associated with the socket
// Get the current setting for this option
// This isn't needed, but it shows how to get the current setting
var currentSetting = clientSocket.Control.NoDelay;
// Don't disable the nagle algorithm
clientSocket.Control.NoDelay = false;
// Now you can use the StreamSocket to call one of the
// ConnectAsync methods
StreamSocketListener ソケットの制御
StreamSocketListener は、TCP ストリーム ソケットを使った着信ネットワーク接続のリッスンをサポートします。StreamSocketListener の詳細オプションは 1 つだけです。
- StreamSocketListener.QualityOfService: StreamSocketListener オブジェクトで接続を受信したときに作成される StreamSocket オブジェクトに対して設定するサービスの品質を示します。
このサービスの品質は、StreamSocketListener オブジェクトで接続を受信したときに作成される StreamSocket オブジェクトでパケットを受信するスレッドの優先順位に影響します。サービスの品質には、SocketQualityOfService 列挙の 2 つの値のいずれかを設定できます。 接続を受信したときに StreamSocket が作成される際の既定の設定は normal です。 lowLatency に設定すると、作成された StreamSocket でパケットを受信するスレッドの優先順位が高くなります。通常、このオプションを使うのは、オーディオ アプリのようなタイミングが非常に重要なアプリの接続を受け入れる場合だけです。
次の例では、StreamSocketListener を作成し、タイミングが重要なアプリの StreamSocketListener.QualityOfService を lowLatency に設定します。その後は、StreamSocketListener に用意されている他のメソッドを使って着信接続要求のリッスンを開始することができます。
var listenSocket = new Windows.Networking.Sockets.StreamSocketListener();
// The control object is associated with the socket
// Get the current setting for quality of service
// This isn't needed, but it shows how to get the current setting
var currentSetting = listenSocket.Control.QualityOfService;
// Set quality of service to low latency
listenSocket.Control.QualityOfService = SocketQualityOfService.LowLatency;
// Now you can use the StreamSocketListener to
// bind to a service name and begin listening for
// incoming connection requests
注釈
制御データ以外にも、主要なクラスにソケットの追加情報を提供する同様の関連クラスは存在します。その例を次に示します。
- DatagramSocketInformation: DatagramSocket オブジェクトのソケット情報を提供します。
- StreamSocketInformation: StreamSocket オブジェクトのソケット情報を提供します。
- StreamSocketListenerInformation: StreamSocketListener オブジェクトのソケット情報を提供します。
ソケットの追加情報にアクセスするモデルも、制御データにアクセスする場合と設計は同じです。以下では StreamSocket を例に説明しています。
- StreamSocket を作成します。
- StreamSocket.Information プロパティを使って、StreamSocket オブジェクトに関連付けられている StreamSocketInformation インスタンスを取得します。
- StreamSocketInformation インスタンスのプロパティを取得してソケットの追加情報を取得します。
ソケット情報とソケット制御のクラスの間には大きな違いが 1 つあります。StreamSocketControl インスタンスのプロパティは、読み取りまたは書き込み (取得または設定) が可能です。それに対し、StreamSocketInformation インスタンスのプロパティは読み取り専用 (取得のみ) です。StreamSocketControl インスタンスと StreamSocketInformation インスタンスのどちらのプロパティの値も、StreamSocket の作成後であればいつでも取得できます。ただし、接続操作やソケットをバインドする操作をアプリから行うときは、必ず StreamSocketControl インスタンスのプロパティを先に設定しておく必要があります。
関連トピック
その他
TLS/SSL を使ってソケット接続のセキュリティを確保する方法
リファレンス