次の方法で共有


Microsoft .NET Framework SDK Net Classes :Managed Codeでのネットワーク アプリケーションの記述

Lance Olson
Microsoft Corporation

概要: この記事は、インターネット上でデータの送受信を行うアプリケーションを記述するための Microsft .NET Framework SDK Managed Code フレームワークの概要を説明しています。

注意   この記事で説明している QuickStart ドキュメントを含む Microsoft .NET Framework SDK などのドキュメントは、こちらから入手できます (英語サイトです)。

注意   この記事は ASP+ (Active Server Pages+) などの Microsoft .NET Framework SDK Technology Preview および Common Language Runtime 環境に関連する主要な概念に精通していることを前提にしています。

注意   この記事で使用されている "Net Classes " という用語は、Microsoft .NET Framework SDK の System.Net 名前空間に含まれるクラスのセットのことです。この用語を Microsoft .NET イニシアティブと混同しないようにしてください。Microsoft .NET イニシアティブは https://www.microsoft.com/isapi/gomscom.asp?TARGET=/net/default.asp で詳細に説明されています。Net Classes は、Microsoft .NET イニシアティブを構成する数多くあるテクノロジの中の 1 つです。

目次

はじめに
Net Classes の使用方法
Net Classes と WinInet との比較
Net Classes とは
Web 上のリソースとの対話
機能の詳細について
むすび

はじめに

.NET Framework SDK Technology Preview の主要な機能は、SDK のランタイム機能を使用するアプリケーションを構築するための豊富なプラットフォームを提供するために設計された、クラスの共通フレームワークです。このフレームワークは以下の項目をサポートします。

  • Data は、XML および ADO スタイルのデータ操作を公開するクラスです。

  • Win Forms は、Windows GUI アプリケーションおよび豊富なコントロールの記述を簡単にするクラスです。

  • ASP+ は、サーバー ベースの Web アプリケーションの構築をサポートします。Web アプリケーションとは Web UI (HTML または WML) と XML Web サービスの両方です。

  • 基本型は、残りのフレームワークが文字列、コレクション、および配列の操作などの共通タスクのために使用するベース クラスです。

  • サービスは、Windows サービス アプリケーション、Microsoft メッセージ キュー、およびその他のシステム レベルの機能と共に動作するためのサポートです。

  • ネットワークは、データの送受信にインターネット プロトコルを使用するアプリケーションの構築のサポートを提供するクラス群です。

この記事では、フレームワークの Net Classes の領域内部を詳しく見ていきます。これらのクラスが、インターネット上でデータの送受信を行う優れたアプリケーションの記述を容易にする方法に焦点を当てています。

Net Classes の使用方法

Net Classes を使用して記述できるアプリケーションは広範囲におよびますが、基本設計には 3 つの主要な目標があります。設計目標を理解すると、クラスがどの程度アプリケーションにとって有益かということがよく分かります。もし、これらの機能のいくつかについてよく知らなくても、以下で詳細を説明するので心配する必要はありません。

  1. Net Classes は、Managed Codeでネットワーク アプリケーションを記述するための簡単で、完全なソリューションを提供します。

    Net Classes は、階層的なアプローチを使用して、アプリケーションの必要性に応じてさまざまなレベルのコントロールを使用して、アプリケーションがネットワークにアクセスすることを可能にします。これらのレベルによってカバーされる範囲は、ソケットの細かい単位の制御から一般的な要求/応答モデルまで、今日のインターネット上のシナリオをほぼすべてを含みます。さらに、このモデルは拡張可能なのでインターネットが発展しても、アプリケーションと共に動作しつづけます。

  2. Net Classes は、HTTP プロトコルの強固なインプリメンテーションを公開します。

    大部分の Web トラフィックが HTTP プロトコル上を行き交っているので、HTTP プロトコルのアプリケーション プロトコルとしての重要性は顕著です。 Net Classes は、ほとんどの HTTP 1.1 プロトコル機能をサポートしています。高度な機能には、パイプライン処理、チャンク処理、認証、事前認証、暗号化、プロキシ サポート、サーバー証明書検証、接続管理、および HTTP 拡張が含まれます。

  3. Net Classes は、スケーラブルで、高性能な ASP+ (Active Server Pages+) 中階層アプリケーションを記述するために設計されています。

    今日の Web サーバーにおける共通のシナリオでは、1 人のクライアントのブラウザ要求の結果として、バック エンド サーバーまたは外部サーバーに対して複数の要求が作成されます。このシナリオでは、高い負荷に耐えられる強力な中間層ネットワーク スタックを必要とします。Net Classes はこの顧客の必要性を明確に念頭において設計されました。接続管理、パイプライン処理、Keep-Alive、および非同期の送受信のような機能は中間層の強力なサポートを確実にします。さらに、Net Classes は総合的なフレームワークの一部なので、権限の借用やキャッシュなどの ASP+ 機能との統合はシームレスに行うことができます。

Net Classes と WinInet との比較

アプリケーションがインターネット プロトコルを使用してデータの送受信を行えるという点では、Net Classes は Microsoft の WinInet API と似ています。ただし、Net Classes はその設計と機能において大きく異なります。上記の設計目標から推測できるかもしれませんが、最も大きな違いは Net Classes はストレスの多いサーバー環境に耐えることに重点を置いて設計されたという点です。

Net Classes とは

Net Classes を使用して記述したコードをいくつか詳しく見ていきましょう。論理的な面からみると、Net Classes は 3 つの層を含んでいます。要求/応答層、アプリケーション プロトコル層、およびトランスポート層です。WebRequest クラスおよび WebResponse クラスは、要求 / 応答層に位置します。HTTP クラス、TCP クラス、および UDP クラスは、アプリケーション プロトコル層を形成します。ソケットはトランスポート層に位置します。TCP/UDP およびソケットは System.Net.Sockets 名前空間に存在しますが、WebRequest/WebResponse および HTTP は System.Net 名前空間に存在します。

図 1. Net Classes

以下に、各層の使用法を示したコードサンプルを示しています。

要求/応答モデル

要求/応答モデルは最上位層で、Web 上のリソースにアクセスする簡単な手段を提供します。このサンプルは Web ページの取得方法およびコンソール アプリケーションの画面に Web ページの内容を書き込む方法を示しています。

Visual Basic の使用


  
' サーバー ストリームを取得するために使用する変数を設定します。
Dim WReq As WebRequest
Dim WResp As WebResponse
Dim sr As StreamReader

' URI の .Create() メソッドに渡される WebRequest オブジェクト
' を作成します。その後、 .GetResponse() を呼び出して、サーバー
' からの応答を取得します。WebRequestFactory は常に要求を作成
' するために使用されることに注意してください。
' これが行われる理由を順を追って詳しく見ていきます。

WReq = WebRequestFactory.Create("https://www.microsoft.com/default.htm")
WResp = WReq.GetResponse()

' サーバーから読み取り可能なストリームを取得します。コンソールに
' 書き込むために、そのデータを ASCII にエンコードします。
sr = new StreamReader(WResp.GetResponseStream(), Encoding.ASCII)

' テキストの読み取りに使用する変数を宣言します。
Dim Buffer(1024) As Char
Dim bytesread As Integer
Dim length As Integer
length = 1024

' ストリームから読み取り、すべてのデータをコンソールに書き込みます。
bytesread = sr.Read(Buffer, 0, length)
Do while (bytesread > 0)

   Console.Write( Buffer,0, bytesread)
   bytesread = sr.Read( Buffer, 0, length)

Loop

' 終了時にストリームを閉じます。
sr.Close

C# の使用


  
// URI の .Create() メソッドに渡される WebRequest オブジェクト
// を作成します。その後、.GetResponse() を呼び出して、サーバー
// からの応答を取得します。
WebRequest WReq = WebRequestFactory.Create()
    ("https://www.microsoft.com/default.htm");
WebResponse WResp = WReq.GetResponse();

// サーバーから読み取り可能なストリームを取得します。コンソールに
// 書き込むために、そのデータを ASCII にエンコードします。
StreamReader sr = new StreamReader(WResp.GetResponseStream(),
    Encoding.ASCII);


// テキストの読み取りに使用する変数を宣言します。
int length = 1024;
char [] Buffer = new char[1024];
int bytesread = 0;

// ストリームから読み取り、すべてのデータをコンソールに書き込みます。
bytesread = sr.Read( Buffer, 0, length);
while( bytesread > 0 )
{
   Console.Write( Buffer,0, bytesread);
   bytesread = sr.Read( Buffer, 0, length);
}

// 終了時にストリームを閉じます。
sr.Close();

HTTP クラス、TCP クラス、および UDP クラス

HTTP クラスは汎用の要求/応答モデルを、HTTP 固有の機能をより高度のレベルで制御することを提供するいくつかの付加的なプロパティと共に実装します。HTTP 固有の機能とは、ヘッダー、チャンク処理、またはユーザー エージェント文字列の設定をプロパティ レベルで制御するために、オブジェクト モデル内の HTTP プロトコルにアクセスする機能です。ほとんどの場合、データの送受信には WebRequest および WebResponse を使用すれば十分です。WebRequest および WebResponse が公開する詳細レベルが十分でない場合のみ、HttpWebRequest クラスおよび HttpWebResponse クラスを使用する必要があります。以下のサンプルは、ある固有の HttpWebRequest プロパティにアクセスする方法を示しています。この場合は、HTTP の Keep-alive 動作をオフにするため、および Web サーバーからプロトコルのバージョン番号を取得するためのプロパティです。

Visual Basic の使用


  
' VB で暗黙的なキャストを取得するために
' Strict オプションをオフにする必要があります。
Option Strict Off

Dim HttpWReq As HttpWebRequest
Dim HttpWResp As HttpWebResponse
Dim sr As StreamReader
Dim ver As String

' URI の .Create() メソッドに渡される WebRequest オブジェクト
' を作成します。それから .GetResponse() を呼び出して、サーバー
' からの応答を取得します。WebRequestFactory は常に要求を作成
' するために使用されることに注意してください。
' これが行われる理由を順を追って詳しく見ていきます。

HttpWReq = WebRequestFactory.Create("https://www.microsoft.com ")

' Keep-Alive 接続をオフにします。
HttpWReq.KeepAlive = false

HttpWResp = HttpWReq.GetResponse()

' サーバーが返した HTTP プロトコル バージョン番号を参照します。
ver = HttpWResp.Version.ToString

' サーバーから読み取り可能なストリームを取得します。コンソールに
' 書き込むために、そのデータを ASCII にエンコードします。
sr = new StreamReader(HttpWResp.GetResponseStream(), Encoding.ASCII)

...
Webrequest の例と同様にストリームを読み取ります。

C# の使用


  
// URI の .Create() メソッドに渡される WebRequest オブジェクト
// を作成します。それから .GetResponse() を呼び出して、サーバー
// からの応答を取得します。
HttpWebRequest HttpWReq = (HttpWebRequest)WebRequestFactory
    .Create ("https://www.microsoft.com ");

// Keep-Alive 接続をオフにします。
HttpWReq.KeepAlive = false;

HttpWebResponse HttpWResp = (HttpWebResponse)HttpWReq.GetResponse();

// サーバーが返した HTTP プロトコル バージョン番号を参照します。
String ver = HttpWResp.Version.ToString();

//サーバーから読み取り可能なストリームを取得します。コンソールに
// 書き込むために、そのデータを ASCII にエンコードします。
StreamReader sr = new StreamReader(WResp.GetResponseStream(),
    Encoding.ASCII);

...
WebRequest の例と同様にストリームを読み取ります。

TCP と UDP

ユーザー独自のネットワーク プロトコルの記述、UDP パケットの送信、または IP マルチキャストの使用のために、TCP クラスと UDP クラスは大部分のソケット動作を実行すると同時に適切なレベルのアクセスを提供します。

Visual Basic の使用


  
' 新しい TCPClient を作成します。
Dim tcpc As TCPClient
Dim Buffer(32) As Byte
Dim bytes As Integer
Dim server As String

server = "tcpserver"

' サーバーが存在することを確認します。
if DNS.GetHostByName(server)
      = "" Then
   Console.WriteLine("Cannot find the tcpserver")
   Exit Sub
End If

' サーバーに接続します。
if tcpc.Connect(server, 13) = -1 Then
   Console.WriteLine("Cannot connect to server: " + server)
   Exit Sub
End If


' ストリームを取得します。
Dim s As Stream
Dim ServerData as String
s = tcpc.GetStream

' ストリームを読み取って、ASCII に変換します。
bytes = s.Read(Buffer, 0, Buffer.Length)
ServerData = Encoding.ASCII.GetString(Buffer)

' データを表示します。
Console.WriteLine("Received " & bytes & " bytes")
Console.WriteLine("The data received from the server is: " &
    ServerData)

' ストリームを閉じます。
tcpc.Close

C# の使用


  
// 新しい TCPClient を作成します。
TCPClient tcpc = new TCPClient();
Byte[] read = new Byte[32];

// サーバーが存在することを確認します。
if (DNS.GetHostByName("tcpserver") == null)
{
   Console.WriteLine("Cannot find the tcpserver");
   return;
}

// サーバーに接続します。
if (tcpc.Connect(server, 13) == -1)
{
   Console.WriteLine("Cannot connect to server: " + server);
   return;
}

// ストリームを取得します。
Stream s = tcpc.GetStream();

// ストリームを読み取って、ASCII に変換します。
int bytes = s.Read(read, 0, read.Length);
String ServerData = Encoding.ASCII.GetString(read);

// データを表示します。
Console.WriteLine("Received " + bytes + " bytes");
Console.WriteLine("The data received from the server is: " +
    ServerData);

// ストリームを閉じます。
tcpc.Close();

ソケット

Winsock に馴染みのある開発者またはソケットが提供する制御レベルを対象としている開発者にとっては、Net Classes ソケット API は既にご存知の Win32 API と同様であると感じるでしょう。Net Classes 内で、Sockets クラスはManaged Codeからネイティブ コードへの移行点として機能します。ほとんどの場合、Sockets の呼び出しは、単にデータを該当するネイティブ Win32 にマーシャリングします。さらに、必要なセキュリティ チェックを処理します。以下のサンプルの関数は、データを HTTP サーバに送信するためと応答を読み取るために Sockets クラスを使用する方法を示しています。

C# の使用


  
public string DoSocketGet(string server)
{
   // サーバーに書き込むために変数と文字列を設定します。
   Encoding ASCII = Encoding.ASCII;
   string Get = "GET / HTTP/1.1\r\nHost: " + server +
                   "\r\nConnection: Close\r\n\r\n";
   Byte[] ByteGet = ASCII.GetBytes(Get);
   Byte[] RecvBytes = new Byte[256];

   // IPAddress と IPEndPoint は、要求を受信する
   // 端点を表します。
   IPAddress hostadd = DNS.Resolve(server);
   IPEndPoint EPhost = new IPEndPoint(hostadd, 80);
   StringBuilder sb = new StringBuilder();

   // TCP にデータを送信するためのソケットを作成します。
   Socket s = new Socket(AddressFamily.AfINet,
                SocketType.SockStream,
             ProtocolType.ProtTCP);

   // IPEndPoint を使用しているホストに接続します。
   if (s.Connect(EPhost) != 0)
   {
      return "Unable to connect to host";
   }

   // GET テキストをホストに送信します。
   s.Send(ByteGet, ByteGet.Length, 0);

   // 既定のページを受信します。すべてのバイトを受信するまで繰り返します。
   Int32 bytes = s.Receive(RecvBytes, RecvBytes.Length, 0);
   sb.Append( "Default HTML page on " + server + ":\r\n");
   sb.Append( ASCII.GetString(RecvBytes, 0, bytes));

   while (bytes > 0)
   {
      bytes = s.Receive(RecvBytes, RecvBytes.Length, 0);
      sb.Append( ASCII.GetString(RecvBytes, 0, bytes));
   }

   return sb.ToString();
}

Web 上のリソースとの対話

Net Classes は、アプリケーションが Web 上のリソースと簡単に対話できるように設計されました。要求/応答のクラスでは、Web 上のリソースが URI アドレス指定可能である必要があります。つまり、リソースが URI (Uniform Resource Identifier) を使用して解決できることを意味します。今日 Web 上で最も代表的な URI は "http://www.<サーバー名>.com/<パス>" です。URI アドレス指定が可能であるリソースの種類は、静的ページ、動的ページ、アプリケーション、データ、およびサービスです。

メッセンジャ アプリケーションのようなインターネット ベースのアプリケーション、または Napstar のように互いに直接通信するノードとして機能するアプリケーションでは、TCP クラスと UDP クラスが理想的なインターフェイスを提供します。

データはストリームとして表現されます

Net Classes を使用して Web 上のリソースが解決されたとき、送信/受信されるデータは Stream オブジェクトで表現されます。この設計の結果として、いくつかの利点がアプリケーションにもたらされます。

  • Web データの共通の表現方法 - ストリームは、データ送受信の汎用的な方法を提供します。GIF ファイル、HTML、XML、またはその他のデータをダウンロードするとき、アプリケーションはデータをダウンロードするために Stream.Read() を使用します。

  • フレームワークでのストリームの豊富なサポート - ストリームはフレームワークの至るところで使用されているので、ストリームを処理するための豊富なインフラストラクチャのセットがあります。たとえば、FileStream から XML ファイルを読み取っているアプリケーションを、ストリームを取得する数行以外はまったく変更しないで、代わりに NetworkStream から読み取るアプリケーションに変更できます。これらの各ストリームを汎用的な方法で処理すると、モジュール化や強力なコード ベースが促進されます。ネットワークからのデータとローカル ファイル システムからデータには違いがあるので、ネットワーク ストリームを使用して作業するときに理解する必要のある概念が少しあることに注意してください。最も一般的に陥りやすいのは、ネットワーク ストリームが簡単に認識できないことを理解しないことです。ネットワーク データは動的に生成されることが多いので、常に "MyNetStream.Length()" に意味があるとは限りません。このため、フレームワークの Stream ベース クラスは、CanSeekCanRead、および CanWrite など、ストリームの機能を検出するとき有効なメソッドを持っています。アプリケーションがストリームの種類を確認できない場合は、ストリームを使用する前にこれらのメソッドを呼び出す必要があります。

既存の Web サービスとの対話

次のことは、明白なことですがこの点が確実に理解されるように説明します。Net Classes は、構築されているインターネット上で標準プロトコルを使用したネットワークへのアクセスを提供します。つまり、アプリケーションが使用するプロトコルを認識していれば、Net Classes を使用して記述されたアプリケーションは、今日インターネット上で使用可能な既存のプラットフォームやサービスを含めて、インターネット上のすべてのアプリケーションと対話できます。Net Classes は、使用されるプロトコルの暗黙的な必要条件以上の条件をサーバーに求めません。たとえば、HTTP1.1 プロトコルが正しく実装されていれば、Net Classes を使用して記述されたアプリケーションは、すべての Web サーバーからデータをダウンロードができます。

機能の詳細について

Net Classes のいくつかの主要な機能の使用方法について詳しく見ていきましょう。

要求/応答モデル

Net Classes の要求/応答モデルには、WebRequestWebResponse の 2 つの主要なクラスがあります。これらの 2 つのクラスは、ネットワーク上のリソースにアクセスする汎用的な方法を提供します。WebRequest は、ネットワーク要求を表し、RequestURIHeadersCredentials、および ContentType などのプロパティを持ちます。WebRequest の主要なメソッドは、GetRequestStreamGetResponse です。これらに対応する非同期のメソッドは Begin/EndGetRequestStreamBegin/EndGetResponse です。GetRequestStream は、サーバーにデータをアップロードするためのストリームを取得するために使用します。GetResponse は、サーバーから返される応答オブジェクトを取得するために使用します。WebResponse は、要求を処理したサーバーから受信した応答を表します。WebResponse の主要なプロパティは ContentLengthContentTypeHeadersResponseURI、および Status です。WebResponse で最も一般的に使用されるメソッドは、サーバーからデータを読み取る (ダウンロードする) ために使用される GetResponseStream です。

実際のネットワーク要求は、通常 WebRequest.GetResponse 呼び出しが行われるときに送信されます。


  
' URI の .Create() メソッドに渡される WebRequest オブジェクトを作成します。
' WebRequestFactory は、常に要求を作成するために
' 使用されることに注意してください。

Dim MyUri As String
Dim WReq As WebRequest
Dim WResp As WebResponse

MyUri = "https://www.microsoft.com/default.htm"
' Request オブジェクトを作成します。
WReq = WebRequestFactory.Create(MyUri)
' ここで、要求を送信して、応答を取得します。
WResp = WReq.GetResponse


ただし、データを送信する場合に要求が実際送信されるのは、アプリケーションがサーバーから upload stream を要求したときです。

// URI の .Create() メソッドに渡される WebRequest オブジェクトを作成します。
// WebRequestFactory は、常に要求を作成するために
// 使用されることに注意してください。

Dim MyUri As String
Dim WReq As WebRequest
Dim RequestStream As Stream
Dim SomeBytes() As Byte
Dim payload As String

' データをアップロードするための URI です。
MyUri = "http://www.mycorporateuploadsite.com/public/"

' これはアップロード対象のデータです。通常このデータは
' データベース、ファイル、および別のネットワーク ストリームから取得されます。
payload = "Data to be sent to the server"

' Request オブジェクトを作成します。
WReq = WebRequestFactory.Create(MyUri)

' ペイロードを ASCII エンコードします。
SomeBytes = System.Text.Encoding.ASCII.GetBytes(payload)

' WebRequest プロパティの一部を設定します。
WReq.Method = "POST"
WReq.ContentType = "application/x-www-form-urlencoded"
WReq.ContentLength = SomeBytes.Length

' 要求ストリームを取得して、データを書き込みます。
RequestStream = WReq.GetRequestStream
RequestStream.Write(SomeBytes, 0, SomeBytes.Length)
RequestStream.Close

アプリケーションにとって意味があるのは応答なので、アプリケーションは要求が実際に送信される瞬間について細かく知る必要はありません。アプリケーション開発者にとって知る必要がある最も重要なことは、WebRequest.GetResponse メソッドが呼び出されるときにアプリケーションが応答を取得するということです。(異常がある場合は例外です)。

WebRequest および WebResponse は FTP、HTTP、および SMTP など多数のインターネット プロトコルをサポートするために、拡張可能な方法で設計されてきました。現在、HTTP はサポートされているプロトコルとして、また FTP は "プラグイン可能" なプロトコルのサンプルとして SDK に同梱されています。WebRequest を作成するために、URI が WebRequestFactory.Create メソッドに渡されます。このメソッドは URI のスキーマ (たとえば http: や ftp:) を参照して、そのスキーマに基づいた元になるインプリメンテーション クラスを選択します。この選択の処理過程はアプリケーションには透過的です。そのため、アプリケーションがそのスキーマのプロトコル固有の API にアクセスする必要がない限り変更する必要はありません。上記のオリジナルのサンプルで、WebRequestFactory.Create() の呼び出しに注目してください。


  ' URI の .Create() メソッドに渡される WebRequest オブジェクトを作成します。<br />' WebRequestFactory は常に要求を作成するために<br />' 使用されることに注意してください。<br /><br />Dim MyUri as String<br />MyUri = "https://www.microsoft.com/default.htm"<br />WReq = WebRequestFactory.Create(MyUri)

WebRequest でサポートが提供されているので、通常は必要のないことですが、WebRequestFactory の戻り値はいつでも HttpWebRequest にキャストできます。

プラグイン可能なプロトコル

アプリケーションが WebRequestWebResponse クラスだけを使用しているとき、新しいプロトコルを "プラグ イン" でき、アプリケーションでコードの変更を行う必要なく使用できます。URI スキーマを WebRequestFactory と共に登録することにより、アプリケーション実行中にプロトコル サポートをプラグ インします。登録は WebRequestFactory.Register() メソッドを呼び出すことによって行われます。このメソッドは特に指定しないでも登録されるように、HTTP プロトコルに対して内部的に呼び出されます。ただし、後で任意の数のプロトコルを実装し、登録することは可能です。当然インターネット上には広範なプロトコルが存在するので、このモデルがすべてのシナリオに対して理想的ではありません。"チャット" のような無手順のプロトコル、またはそれ以外の要求/応答モデルにつながるプロトコルは、TCP クラスまたは UDP クラスを使用して実装する方が良いでしょう。場合によっては、Sockets クラスを使用して実装する方が望ましいこともあります。どのレベルが適しているかよく分からない場合は、まず要求/応答モデルから始めます。要求/応答モデルが適してないと思われる場合は、ソケットにレベルを移します。

HTTP

HTTP プロトコルの強固なサポートは、Net Classes の設計と実装において最優先されてきました。下記の API の詳細は、いくつかより高度な HTTP の機能の使用方法を示しています。

チャンク処理

ダウンロードまたはアップロードの開始時に、正確なサイズが不明なデータを送受信する必要があるアプリケーションでは、チャンク処理が便利です。これは、該当するデータがほかのアプリケーションまたはサーバー ロジックに基づいて動的に作成される場合に最も一般的に見られます。チャンクされるデータを送信するには、WebRequestHttpWebRequest にキャストする必要があり、HttpWebRequest.SendChunked プロパティを TRUE に設定する必要があります。


  
' VB で暗黙的なキャストを取得するには
' Strict オプションをオフにする必要があります。
Option Strict Off

Dim MyUri As String
Dim HttpWReq As HttpWebRequest
Dim RequestStream As Stream

' データをアップロードするための URI です。
MyUri = "http://www.mycorporateuploadsite.com/public/"

' Request オブジェクトを作成します。
HttpWReq = WebRequestFactory.Create(MyUri)

' WebRequest プロパティのいくつかを設定します。
HttpWReq.Method = "POST"
HttpWReq.ContentType = "text/xml"
HttpWReq.SendChunked = True

' 要求ストリームを取得し、データを書き込みます。
RequestStream = HttpWReq.GetRequestStream

...ここでは動的なデータを繰り返し読み取り、RequestStream に書き込みます。

' 終了時にストリームを閉じます。そうすることでサーバーが終了したことを認識するので
' チャンクされたデータを送信しているときには特に重要です。
RequestStream.Close

HTTP パイプライン処理

パイプライン処理は、Net Classes が次の要求を送信する前にサーバーからの応答を待つことなく、複数の HTTP 要求をバックエンド サーバーに固定接続で送信できる HTTP 1.1 の機能です。複数のリソースをサーバーから要求しているアプリケーションが、データーベース照合など、サーバー上で操作に時間がかかるある特定のリソースを待機するためにブロックされないので、これはパフォーマンスに大きな影響を及ぼします。図 2 は従来の HTTP の要求/応答動作と比較したパイプライン処理の使用について示しています。パイプライン処理 (右) の場合、クライアントは応答を受信する前に要求を送信するので、3 つの要求を処理する総時間が減っていることが分かります。

図 2. パイプライン処理と従来の HTTP の要求/応答動作

Net Classes 内では既定で見えないところでパイプライン処理が行われます。HttpWebRequest.Pipelined プロパティを FALSE に設定すると、その設定が必要でない特殊な場合にはパイプライン処理が使用できなくなります。


  
' VB で暗黙的なキャストを取得するには
' Strict オプションをオフにする必要があります。
Option Strict Off

Dim MyUri As String
Dim HttpWReq As HttpWebRequest

' 要求する URI です。
MyUri = "http://www.mycorporateuploadsite.com/public/"

' Request オブジェクトを作成します。
HttpWReq = WebRequestFactory.Create(MyUri)

' パイプライン処理をオフにします。
HttpWReq.Pipelined = False

接続管理

Keep-Alive - HTTP 1.0 に実装された Keep-Alive 機能を使用して、クライアントは HTTP を使用してネットワーク リソースを保持でき、稼動中のサーバーへの既存の TCP 接続を閉じて、要求ごとに新しく接続を作成するのではなく、その既存の接続を保持、再利用することによって、より効果的な方法で動作できます。特に指定しない限り Keep-Alive プロパティは、TRUE に設定されています。サーバーがこの動作をサポートしているかぎり、サーバーへの固定接続が作成されます。中間層の ASP+ アプリケーションからバックエンド サーバーにアクセスしている場合、バックエンドで接続がタイムアウトになるまでバックエンド サーバーへの接続は開いたままになることに注意する必要があります。

接続の制限数 - 接続の管理は、ネットワーク アプリケーションでの最適規模と最適パフォーマンスを達成するための重要な機能です。2 台のコンピュータ間で使用する接続の数は、アプリケーションのスループットに大きな影響を与えます。Net Classes を使用するアプリケーションから指定されたサーバーへの既定の接続数は 2 です。この数は、アプリケーション単位で増減できます。以下の図は、接続を 2 つずつ使用して ASP+ サーバーに接続している 3 つのクライアントを示しています。サーバーは、接続を 6 つ使用してバックエンド コンピュータに送受信します。

図 3. 接続を 2 つずつ使用して ASP+ サーバーに接続している 3 つのクライアント

使用する接続の最適数は、アプリケーションが実行されているシナリオに依存します。そのため、接続の特定の推奨値を求めるよりも、既定値を使用しアプリケーションのスループットのベースラインを測定し、パフォーマンスへの影響度を見ながらこの既定値を変更していくことをお勧めします。たとえば、既定値を 2 に設定し、それを 4 に変更していく方法です。アプリケーションは、複数の接続を持つことの利点と新しい接続を作成するオーバーヘッドの微妙なバランスの上に成り立っているので、一般的に同時接続の数は 100 以上にならないようにします。ある時点では、多くの接続を作成しているアプリケーションは、わずかな接続をうまく使用しているアプリケーションより事実上実行が遅くなります。すばらしいことに、ほとんどの場合 Net Classes は適切な接続数を判断します。非同期 API を使用しているユーザー、またはマルチスレッド方式で同期 API を使用しているユーザーは、静的な ServicePoint.DefaultPersistentConnectionLimit プロパティを使用して接続を変更できます。


  ' 既定値を 2 から 4 に変更する場合、アプリケーションを<br />' 初期化するときに、これを呼び出します。多くの場合、<br />' 2 が接続の最適数であることに注意してください。<br />System.Net.ServicePoint.DefaultPersistentConnectionLimit = 4

接続グループ - Net Classes での接続グループは、1 つのアプリケーション内で特定の要求を定義済みの接続プールに関連付ける方法を提供します。接続レベルの認証を使用しているとき、および中間層アプリケーションからバック エンド コンピュータに多くの要求が送信されているときに、この方法は最も有効です。要求が流れている接続にユーザーを関連付けたいことがよくあります。たとえば、ジョーという名前のユーザーが、彼の給与情報を表示する内部 Web サイトを訪れていると仮定します。ジョーが初めてそのサイトを訪れたとき、ドメイン、ユーザー名、およびパスワードを使用してログインするように求められます。ジョーが訪れている Web サイトは、背後でジョーの Windows NT 資格情報を使用して彼のプロファイルを表すファイルを入手し、異なるバックエンド サーバーに対して HTTP 要求を行っています。その後、ジョーのプロファイルを使用して彼の給与情報を取得します。多くの場合、バック エンド要求は Microsoft NTLM プロトコルを使用して認証されます。この時点で接続はジョーの資格情報で認証されています。次に、スーザンがこのサイトを訪れて彼女の給与情報を要求します。しかし、バックエンド接続はジョーとして認証されているので、バックエンド サーバーはジョーのプロファイルを使用して応答します。いささか極端ではありましたが、この例は接続グループによって要求のいくつかの種類が分けられることの重要性を理解する手助けになります。接続をグループ化するために、要求を行う前に アプリケーションで WebRequest.ConnectionGroupName プロパティを設定します。


  ' URI の .Create() メソッドに渡される WebRequest オブジェクトを作成します。<br />' WebRequestFactory は常に要求を作成するために<br />' 使用されることに注意してください。<br /><br />Dim MyUri as String<br />Dim WReq As WebRequest<br /><br />MyUri = "https://www.microsoft.com/default.htm"<br />WReq = WebRequestFactory.Create(MyUri)<br />WReq.ConnectionGroupName = "Joe" 

認証

Net Classes は、ダイジェスト、基本、Kerberos、NTLM、およびカスタムを含むさまざまなクライアント認証メカニズムをサポートします。認証は、要求を行う前に WebRequest.Credentials オブジェクトを設定して行われます。ダイジェストおよび基本認証の場合、ユーザー名とパスワードを指定します。NTLM または Kerberos 認証の場合、Windows セキュリティが使用され、Credential オブジェクトはユーザー名、パスワード、およびドメインの組み合わせに設定するか、システム既定値を要求できます。


  ' NTLM を使用して保護された内部のサイトに要求を行います。<br /><br />Dim MyUri
      as String<br />Dim WReq As WebRequest<br /><br />MyUri = "http://paychecks/default.aspx"BR>WReq = WebRequestFactory.Create(MyUri)<br />WReq.Credentials = CredentialCache.DefaultCredentials 

基本認証を使用してインターネット サイトに要求する場合は、以下のようになります。


  ' NTLM を使用して保護された内部のサイトに要求を行います。<br /><br />Dim MyUri
      as String<br />Dim WReq As WebRequest<br /><br />MyUri = &amp;quothttp;://www.basicprotectedsite.com/default.aspx"<br />WReq = WebRequestFactory.Create(MyUri)<br />WReq.Credentials = new SingleCredential("username", "password) 

SSL

Net Classes 内では、保護接続 (SSL 3.0) のサポートはシームレスです。URI の始めに https:// が使用されている場合、クラスは暗黙に SSL を使用します。


  ' SSL を使用してサイトの要求を行います。HTTPS URI に注意してください。<br /><br />Dim MyUri as String<br />Dim WReq As WebRequest<br />Dim WResp As WebResponse<br /><br />MyUri = "https://www.sslsecuredsite.com/default.aspx<br />&amp;quotWReq; = WebRequestFactory.Create(MyUri)<br />WResp = WReq.GetResponse

プロキシ サポート

Net Classes での HTTP プロキシ サポートは、要求を基本単位として制御できます。また、このプロキシ サポートはアプリケーションの実行中はグローバルに設定できます。以下の例は、プロキシ サーバーを使用して要求を行う場合に、プロキシをグローバルに設定する方法を示しています。


  ' プロキシ サーバーを使用して外部サイトに要求を行います。<br /><br />Dim MyUri as String<br />Dim WReq As WebRequest<br />Dim WResp As WebResponse<br />Dim proxyObject as DefaultControlObject<br /><br />proxyObject = new DefaultControlObject("myproxyservername", 80)<br /><br />' ホストがローカル、すなわちピリオドがない場合、プロキシの使用を無効にします。<br />proxyObject.ProxyNoLocal = true<br /><br />' グローバルの設定を新しい設定に引き継ぎます。<br />' すべての新しい要求はこのプロキシ情報を使用します。<br />GlobalProxySelection.Select = proxyObject<br /><br />MyUri = "https://www.someexternalsite.com/default.aspx"<br />WReq = WebRequestFactory.Create(MyUri)<br />WResp = WReq.GetResponse 

TCP と UDP

System.Net.Sockets 名前空間で使用可能な TCPClient クラス、TCPListener クラス、および UDPClient クラスは、TCP プロトコルと UDP プロトコルをサポートします。

TCPClient

TCPClient クラスは TCP プロトコルを使用して、端点に接続する簡易的な方法を提供します。このクラスは、NetworkStream オブジェクトを使用する接続上で読み取りまたは書き込みされるデータを公開します。QuickStart ドキュメントから引用した以下の Data/Time クライアントの例を参照してください。

C# の使用


  
using System;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Text;

class Client
{
   public static void Main(String[] args)
   {

      TCPClient tcpc = new TCPClient();
      Byte[] read = new Byte[32];

      if (args.Length != 1)
      {
                  Console.WriteLine("Please specify a server
                                     name in the command line");
                  return;
      }

      String server = args[0];

      // サーバーが存在することを確認します。
      if (DNS.GetHostByName(server) == null)
      {
                  Console.WriteLine("Cannot find server: " +
                                     server);
                  return;
      }

      // サーバーに接続します。
      if (tcpc.Connect(server, 13) == -1)
      {
                  Console.WriteLine("Cannot connect to server: " + server);
                  return;
      }

      // ストリームを取得します。
      Stream s = tcpc.GetStream();

      // ストリームを読み取り、ASCII に変換します。
      int bytes = s.Read(read, 0, read.Length);
      String Time = Encoding.ASCII.GetString(read);

      // データを表示します。
      Console.WriteLine("Received " + bytes + " bytes");
      Console.WriteLine("Current date and time is: " + Time);

      tcpc.Close();
   }
}

TCPListener

TCPListener クラスは、クライアントからの TCP 接続を特定のソケットで受信待ちする機能を提供します。QuickStart ドキュメントから引用した以下の Data/Time クライアントの例を参照してください。

C# の使用


  
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;

class Server
{
   public static void Main()
   {
      DateTime now;
      String strDateLine;
      Encoding ASCII = Encoding.ASCII;

      // ポート 13 で受信待ちします。
      TCPListener tcpl = new TCPListener(13);

      tcpl.Start();

      Console.WriteLine("Waiting for clients to connect");
         Console.WriteLine("Press Ctrl+c to Quit...");

      while (true)
      {
         // 接続されるまで Accept はブロックされます。
                  Socket s = tcpl.Accept();

         // 現在の日時を取得し、
                  // 連結して文字列にします。
                  now = DateTime.Now;
                  strDateLine = now.ToShortDateString() + " " +
                  now.ToLongTimeString();

                  // 文字列をバイト配列に変換して、送信します。
                  Byte[] byteDateLine =
ASCII.GetBytes(strDateLine.ToCharArray());
         s.Send(byteDateLine, byteDateLine.Length, 0);
         Console.WriteLine("Sent " + strDateLine);
      }
   }
}

UDPClient とマルチキャスト

UDPClient クラスは、UDPClient.JoinMulticastGroupUDPClient.DropMulticastGroup などのグループ管理メソッドを使用してネットワーク データグラムと IP マルチキャストの送信を容易にします。

コード アクセス

WebPermissions クラスと SocketPermissions クラスを使用して、アプリケーションは着信接続を受け入れることができ、また URI またはトランスポート アドレスそれぞれに基づいたほかのホストに接続できます。この 2 つの権限は、アクセスの許可/拒否に対して同じポリシーを持っています。これらは 2 つの異なる抽象レベルで動作するので、異なる API として存在します。WebPermissionsSocketPermissions は、単独で使用できるだけでなく組み合わせて使用することもできます。

WebPermissions

WebPermissions クラスは、アプリケーションの URI をアクセスまたはエクスポートする権限を制御します。

SocketPermissions

SocketPermissions クラスは、アプリケーションがローカル トランスポート アドレスで接続を受け入れる権限、またはホスト名、ポート番号、およびトランスポートが指定するあるトランスポート アドレス上のアプリケーションにコンタクトする権限を制御します。

むすび

Net Classes の詳細およびその他の開発者向け情報は MSDN Online .NET Information (英語サイトです) MSDN Library Online にあります。