次の方法で共有


トランスポート: UDP

UDP トランスポートのサンプルでは、カスタム Windows Communication Foundation (WCF) トランスポートとして UDP ユニキャストとマルチキャストを実装する方法を示します。 このサンプルでは、チャネル フレームワークを使用し、WCF のベスト プラクティスに従って、WCF でカスタム トランスポートを作成するための推奨手順について説明します。 カスタム トランスポートを作成する手順は次のとおりです。

  1. ChannelFactory と ChannelListener がサポートするチャネル のメッセージ交換パターン (IOutputChannel、IInputChannel、IDuplexChannel、IRequestChannel、または IReplyChannel) を決定します。 次に、これらのインターフェイスのセッションフル バリエーションをサポートするかどうかを決定します。

  2. Message Exchange パターンをサポートするチャネル ファクトリとリスナーを作成します。

  3. ネットワーク固有の例外が、 CommunicationExceptionの適切な派生クラスに正規化されていることを確認します。

  4. チャネル スタックにカスタム トランスポートを追加する <binding> 要素を追加します。 詳細については、「 バインド要素の追加」を参照してください。

  5. 新しいバインド要素を構成システムに公開するバインド要素拡張セクションを追加します。

  6. 他のエンドポイントと機能を通信するためのメタデータ拡張機能を追加します。

  7. 適切に定義されたプロファイルに従ってバインド要素のスタックを事前に構成するバインディングを追加します。 詳細については、「 標準バインディングの追加」を参照してください。

  8. バインド セクションとバインド構成要素を追加して、バインドを構成システムに公開します。 詳細については、「 構成サポートの追加」を参照してください。

メッセージ交換パターン

カスタム トランスポートを作成する最初の手順は、トランスポートに必要なメッセージ交換パターン (MEP) を決定することです。 次の 3 つの MEP から選択できます。

  • Datagram (IInputChannel/IOutputChannel)

    データグラム MEP を使用する場合、クライアントは "ファイア アンド フォーゲット" 交換を使用してメッセージを送信します。 このような交換では、配信の成否について帯域外での確認が必要になります。 メッセージが転送中に失われ、サービスに到達しない可能性があります。 クライアント側で送信操作が正常に完了した場合、リモート エンドポイントがメッセージを受信したという保証はありません。 データグラムは、信頼性の高いプロトコルやセキュリティで保護されたプロトコルなど、独自のプロトコルをその上に構築できるため、メッセージングの基本的な構成要素です。 クライアント データグラム チャネルは IOutputChannel インターフェイスを実装し、サービス データグラム チャネルは IInputChannel インターフェイスを実装します。

  • Request-Response (IRequestChannel/IReplyChannel)

    この MEP では、メッセージが送信され、応答が受信されます。 このパターンは、要求と応答のペアで構成されます。 要求/応答呼び出しの例としては、リモート プロシージャ コール (RPC) とブラウザーの GET があります。 このパターンは、半二重とも呼ばれます。 この MEP では、クライアント チャネルは IRequestChannel を実装し、サービス チャネルは IReplyChannelを実装します。

  • 双方向 (IDuplexChannel)

    双方向 MEP を使用すると、任意の数のメッセージをクライアントから送信し、任意の順序で受信できます。 双方向 MEP は電話での会話のようなもので、話されている各単語はメッセージです。 この MEP では両方の側が送受信できるため、クライアント チャネルとサービス チャネルによって実装されるインターフェイスは IDuplexChannel

これらの各 MEP は、セッションをサポートすることもできます。 セッション対応チャネルによって提供される追加の機能は、チャネルで送受信されるすべてのメッセージを関連付けるということです。 Request-Response パターンは、要求と応答が関連付けられるスタンドアロンの 2 メッセージ セッションです。 これに対し、セッションをサポートする Request-Response パターンは、そのチャネル上のすべての要求と応答のペアが相互に関連付けられることを意味します。 これにより、合計 6 つの MEP (Datagram、Request-Response、Duplex、Datagram with sessions、Request-Response with sessions、Duplex with sessions) を選択できます。

UDP トランスポートの場合、UDP は本質的に "ファイア アンド フォーゲット" プロトコルであるため、サポートされている MEP はデータグラムだけです。

ICommunicationObject と WCF オブジェクトのライフサイクル

WCF には、通信に使用される IChannelIChannelFactoryIChannelListener などのオブジェクトのライフサイクルを管理するために使用される共通のステート マシンがあります。 これらの通信オブジェクトが存在できる状態は 5 つあります。 これらの状態は、 CommunicationState 列挙体によって表され、次のようになります。

  • 作成済み: これは、最初にインスタンス化されたときの ICommunicationObject の状態です。 この状態では入出力 (I/O) は発生しません。

  • 開く: Open が呼び出されると、オブジェクトはこの状態に遷移します。 この時点で、プロパティは変更不可になり、入力/出力を開始できます。 この遷移は、Created 状態からのみ有効です。

  • 開かれた: オブジェクトは、開いているプロセスが完了すると、この状態に遷移します。 この遷移は、開始状態からのみ有効です。 この時点で、オブジェクトは完全に転送に使用できます。

  • Closing: 正常なシャットダウンのために Close が呼び出されると、オブジェクトはこの状態に遷移します。 この遷移は、Opened 状態からのみ有効です。

  • Closed: Closed 状態のオブジェクトは使用できなくなりました。 一般に、ほとんどの構成は検査のために引き続きアクセスできますが、通信は行われません。 この状態は破棄と同じです。

  • Faulted: Faulted 状態では、オブジェクトは検査にアクセスできますが、使用できなくなります。 回復不可能なエラーが発生すると、オブジェクトはこの状態に遷移します。 この状態からの唯一の有効な遷移は、 Closed 状態です。

状態遷移ごとに発生するイベントがあります。 Abort メソッドはいつでも呼び出すことができます。これにより、オブジェクトは現在の状態から Closed 状態に直ちに遷移します。 Abortを呼び出すと、未完了の作業が終了します。

チャネル ファクトリとチャネル リスナー

カスタム トランスポートを記述する次の手順は、クライアント チャネルとサービス チャネルのIChannelListenerIChannelFactoryの実装を作成することです。 チャネル レイヤーは、チャネルの構築にファクトリ パターンを使用します。 WCF には、このプロセスの基本クラス ヘルパーが用意されています。

このサンプルでは、ファクトリ実装は UdpChannelFactory.cs に含まれており、リスナーの実装は UdpChannelListener.cs に含まれています。 IChannel実装は、UdpOutputChannel.csとUdpInputChannel.csにあります。

UDP チャネル ファクトリ

UdpChannelFactoryChannelFactoryBaseから派生します。 このサンプルでは、メッセージ エンコーダーのメッセージ バージョンへのアクセスを提供するために、 GetProperty をオーバーライドします。 また、ステート マシンの遷移時にBufferManagerのインスタンスを破棄できるように、このサンプルはOnCloseをオーバーライドします。

UDP 出力チャネル

UdpOutputChannelIOutputChannelを実装します。 コンストラクターは、引数を検証し、渡されたEndPointに基づいてEndpointAddressオブジェクトを作成します。

this.socket = new Socket(this.remoteEndPoint.AddressFamily, SocketType.Dgram, ProtocolType.Udp);

チャネルが閉じる際には、正常終了することも異常終了することもあります。 チャネルが正常に閉じている場合、ソケットは閉じられ、基底クラス OnClose メソッドへの呼び出しが行われます。 これが例外をスローした場合、インフラストラクチャはチャネルをクリーンにするために Abort を呼び出します。

this.socket.Close(0);

次に、 Send()BeginSend()/EndSend()を実装します。 これは、2 つの主要なセクションに分かれています。 まず、メッセージをバイト配列にシリアル化します。

ArraySegment<byte> messageBuffer = EncodeMessage(message);

次に、結果のデータをネットワーク上に送信します。

this.socket.SendTo(messageBuffer.Array, messageBuffer.Offset, messageBuffer.Count, SocketFlags.None, this.remoteEndPoint);

The UdpChannelListener

サンプルが実装する UdpChannelListener は、 ChannelListenerBase クラスから派生します。 1 つの UDP ソケットを使用してデータグラムを受信します。 OnOpen メソッドは、非同期ループで UDP ソケットを使用してデータを受信します。 その後、データはメッセージ エンコード フレームワークを使用してメッセージに変換されます。

message = MessageEncoderFactory.Encoder.ReadMessage(new ArraySegment<byte>(buffer, 0, count), bufferManager);

同じデータグラム チャネルは複数のソースから到着したメッセージを表しているため、 UdpChannelListener はシングルトン リスナーです。 このリスナーには、最大で 1 つのアクティブな IChannel が一度に関連付けられています。 このサンプルでは、 AcceptChannel メソッドによって返されるチャネルが後で破棄された場合にのみ、別のチャネルが生成されます。 メッセージを受信すると、このシングルトン チャネルにエンキューされます。

UdpInputChannel

UdpInputChannel クラスは、IInputChannelを実装します。 これは、 UdpChannelListenerのソケットによって設定される受信メッセージのキューで構成されます。 これらのメッセージは、 IInputChannel.Receive メソッドによってデキューされます。

バインド要素の追加

ファクトリとチャネルがビルドされたので、バインドを使用して ServiceModel ランタイムに公開する必要があります。 バインディングは、サービス アドレスに関連付けられている通信スタックを表すバインディング要素のコレクションです。 スタック内の各要素は、 <binding> 要素によって表されます。

このサンプルでは、バインド要素は UdpTransportBindingElementされ、 TransportBindingElementから派生します。 次のメソッドをオーバーライドして、バインディングに関連付けられているファクトリをビルドします。

public IChannelFactory<TChannel> BuildChannelFactory<TChannel>(BindingContext context)
{
    return (IChannelFactory<TChannel>)(object)new UdpChannelFactory(this, context);
}

public IChannelListener<TChannel> BuildChannelListener<TChannel>(BindingContext context)
{
    return (IChannelListener<TChannel>)(object)new UdpChannelListener(this, context);
}

また、 BindingElement を複製し、スキーム (soap.udp) を返すメンバーも含まれています。

トランスポート バインド要素のメタデータ サポートの追加

トランスポートをメタデータ システムに統合するには、ポリシーのインポートとエクスポートの両方をサポートする必要があります。 これにより、 ServiceModel メタデータ ユーティリティ ツール (Svcutil.exe) を使用してバインディングのクライアントを生成できます。

WSDL サポートの追加

バインディング内のトランスポート バインド要素は、メタデータ内のアドレス指定情報をエクスポートおよびインポートする役割を担います。 SOAP バインドを使用する場合は、トランスポート バインド要素もメタデータ内の正しいトランスポート URI をエクスポートする必要があります。

WSDL エクスポート

アドレス指定情報をエクスポートするために、 UdpTransportBindingElementIWsdlExportExtension インターフェイスを実装します。 ExportEndpointメソッドは、WSDL ポートに正しいアドレス指定情報を追加します。

if (context.WsdlPort != null)
{
    AddAddressToWsdlPort(context.WsdlPort, context.Endpoint.Address, encodingBindingElement.MessageVersion.Addressing);
}

ExportEndpoint メソッドのUdpTransportBindingElement実装では、エンドポイントが SOAP バインディングを使用する場合にもトランスポート URI がエクスポートされます。

WsdlNS.SoapBinding soapBinding = GetSoapBinding(context, exporter);
if (soapBinding != null)
{
    soapBinding.Transport = UdpPolicyStrings.UdpNamespace;
}

WSDL インポート

WSDL インポート システムを拡張してアドレスのインポートを処理するには、Svcutil.exe.config ファイルに示すように、Svcutil.exe の構成ファイルに次の構成を追加する必要があります。

<configuration>
  <system.serviceModel>
    <client>
      <metadata>
        <policyImporters>
          <extension type=" Microsoft.ServiceModel.Samples.UdpBindingElementImporter, UdpTransport" />
        </policyImporters>
      </metadata>
    </client>
  </system.serviceModel>
</configuration>

Svcutil.exeを実行する場合、Svcutil.exe に WSDL インポート拡張をロードさせるには、次の 2 つのオプションがあります。

  1. /SvcutilConfig:<file>を使用して、構成ファイル Svcutil.exe ポイントします。

  2. 設定セクションを Svcutil.exe.config と同じディレクトリに追加します Svcutil.exe。

UdpBindingElementImporter型は、IWsdlImportExtension インターフェイスを実装します。 ImportEndpoint メソッドは、WSDL ポートからアドレスをインポートします。

BindingElementCollection bindingElements = context.Endpoint.Binding.CreateBindingElements();
TransportBindingElement transportBindingElement = bindingElements.Find<TransportBindingElement>();
if (transportBindingElement is UdpTransportBindingElement)
{
    ImportAddress(context);
}

ポリシーサポートの追加

カスタム バインド要素は、サービス エンドポイントの WSDL バインド内のポリシー アサーションをエクスポートして、そのバインド要素の機能を表現できます。

ポリシーのエクスポート

UdpTransportBindingElement型は、ポリシーのエクスポートのサポートを追加するIPolicyExportExtensionを実装します。 その結果、 System.ServiceModel.MetadataExporter には、それを含むバインディングのポリシーの生成に UdpTransportBindingElement が含まれます。

IPolicyExportExtension.ExportPolicyでは、UDP のアサーションと、マルチキャスト モードの場合は別のアサーションを追加します。 これは、マルチキャスト モードが通信スタックの構築方法に影響を与えるので、両側の間で調整する必要があるためです。

ICollection<XmlElement> bindingAssertions = context.GetBindingAssertions();
XmlDocument xmlDocument = new XmlDocument();
bindingAssertions.Add(xmlDocument.CreateElement(
UdpPolicyStrings.Prefix, UdpPolicyStrings.TransportAssertion, UdpPolicyStrings.UdpNamespace));
if (Multicast)
{
    bindingAssertions.Add(xmlDocument.CreateElement(
        UdpPolicyStrings.Prefix,
        UdpPolicyStrings.MulticastAssertion,
        UdpPolicyStrings.UdpNamespace));
}

カスタム・トランスポート・バインディング・エレメントはアドレス指定の処理を担当するため、IPolicyExportExtension上のUdpTransportBindingElement実装では、使用されている WS-Addressing のバージョンを示す適切な WS-Addressing・ポリシー・アサーションのエクスポートも処理する必要があります。

AddWSAddressingAssertion(context, encodingBindingElement.MessageVersion.Addressing);

ポリシーのインポート

ポリシー インポート システムを拡張するには、Svcutil.exe.config ファイルに示すように、Svcutil.exe の構成ファイルに次の構成を追加する必要があります。

<configuration>
  <system.serviceModel>
    <client>
      <metadata>
        <policyImporters>
          <extension type=" Microsoft.ServiceModel.Samples.UdpBindingElementImporter, UdpTransport" />
        </policyImporters>
      </metadata>
    </client>
  </system.serviceModel>
</configuration>

次に、登録されたクラス (IPolicyImporterExtension) からUdpBindingElementImporterを実装します。 ImportPolicy()では、名前空間内のアサーションを調べて、トランスポートを生成するためのアサーションを処理し、それがマルチキャストであるかどうかを確認します。 また、バインディング アサーションの一覧から、処理するアサーションを削除する必要があります。 ここでも、Svcutil.exeを実行する場合、統合には次の 2 つのオプションがあります。

  1. /SvcutilConfig:<file>を使用して、構成ファイル Svcutil.exe ポイントします。

  2. 設定セクションを Svcutil.exe.config と同じディレクトリに追加します Svcutil.exe。

標準バインドの追加

バインド要素は、次の 2 つの方法で使用できます。

  • カスタム バインドを使用する: カスタム バインドを使用すると、ユーザーは任意のバインド要素のセットに基づいて独自のバインドを作成できます。

  • バインディング要素を含むシステム提供のバインディングを使用する。 WCF には、 BasicHttpBindingNetTcpBindingWsHttpBindingなど、システム定義のバインドが多数用意されています。 これらの各バインディングは、明確に定義されたプロファイルに関連付けられます。

このサンプルでは、Bindingから派生したSampleProfileUdpBindingにプロファイル バインドを実装しています。 SampleProfileUdpBindingには、UdpTransportBindingElementTextMessageEncodingBindingElement CompositeDuplexBindingElementReliableSessionBindingElementという最大 4 つのバインド要素が含まれています。

public override BindingElementCollection CreateBindingElements()
{
    BindingElementCollection bindingElements = new BindingElementCollection();
    if (ReliableSessionEnabled)
    {
        bindingElements.Add(session);
        bindingElements.Add(compositeDuplex);
    }
    bindingElements.Add(encoding);
    bindingElements.Add(transport);
    return bindingElements.Clone();
}

カスタム標準バインド インポーターの追加

Svcutil.exe と WsdlImporter 型は、既定でシステム定義のバインドを認識してインポートします。 それ以外の場合、バインドは CustomBinding インスタンスとしてインポートされます。 Svcutil.exe と WsdlImporterSampleProfileUdpBinding をインポートできるようにするために、 UdpBindingElementImporter はカスタム標準バインディング インポーターとしても機能します。

カスタム標準バインド インポーターは、IWsdlImportExtension インターフェイスにImportEndpoint メソッドを実装して、メタデータからインポートされたCustomBinding インスタンスを調べて、特定の標準バインドによって生成された可能性があるかどうかを確認します。

if (context.Endpoint.Binding is CustomBinding)
{
    Binding binding;
    if (transportBindingElement is UdpTransportBindingElement)
    {
        //if TryCreate is true, the CustomBinding will be replace by a SampleProfileUdpBinding in the
        //generated config file for better typed generation.
        if (SampleProfileUdpBinding.TryCreate(bindingElements, out binding))
        {
            binding.Name = context.Endpoint.Binding.Name;
            binding.Namespace = context.Endpoint.Binding.Namespace;
            context.Endpoint.Binding = binding;
        }
    }
}

一般に、カスタム標準バインド インポーターを実装するには、インポートされたバインド要素のプロパティを調べて、標準バインドによって設定された可能性があるプロパティのみが変更され、その他のすべてのプロパティが既定値であることを確認する必要があります。 標準バインド インポーターを実装するための基本的な方法は、標準バインドのインスタンスを作成し、バインド要素から標準バインドがサポートする標準バインド インスタンスにプロパティを伝達し、標準バインドのバインド要素をインポートされたバインド要素と比較することです。

構成サポートの追加

構成を介してトランスポートを公開するには、2 つの構成セクションを実装する必要があります。 1 つ目は、UdpTransportBindingElementBindingElementExtensionElementです。 これは、 CustomBinding 実装がバインディング要素を参照できるようにするためです。 2 つ目は、SampleProfileUdpBindingConfigurationです。

Binding 要素拡張要素

UdpTransportElementセクションは、構成システムにBindingElementExtensionElementを公開するUdpTransportBindingElementです。 いくつかの基本的なオーバーライドを使用して、構成セクション名、バインド要素の型、およびバインド要素の作成方法を定義します。 次のコードに示すように、拡張機能セクションを構成ファイルに登録できます。

<configuration>
  <system.serviceModel>
    <extensions>
      <bindingElementExtensions>
        <add name="udpTransport" type="Microsoft.ServiceModel.Samples.UdpTransportElement, UdpTransport" />
      </bindingElementExtensions>
    </extensions>
  </system.serviceModel>
</configuration>

この拡張機能は、トランスポートとして UDP を使用するためにカスタム バインドから参照できます。

<configuration>
  <system.serviceModel>
    <bindings>
      <customBinding>
       <binding configurationName="UdpCustomBinding">
         <udpTransport/>
       </binding>
      </customBinding>
    </bindings>
  </system.serviceModel>
</configuration>

Binding セクション

SampleProfileUdpBindingCollectionElementセクションは、構成システムにStandardBindingCollectionElementを公開するSampleProfileUdpBindingです。 実装の大部分は、SampleProfileUdpBindingConfigurationElementから派生したStandardBindingElementに委任されます。 SampleProfileUdpBindingConfigurationElementには、SampleProfileUdpBindingのプロパティに対応するプロパティと、ConfigurationElement バインドからマップする関数があります。 最後に、次のサンプル コードに示すように、SampleProfileUdpBindingOnApplyConfiguration メソッドをオーバーライドします。

protected override void OnApplyConfiguration(string configurationName)
{
    if (binding == null)
        throw new ArgumentNullException("binding");

    if (binding.GetType() != typeof(SampleProfileUdpBinding))
    {
        throw new ArgumentException(string.Format(CultureInfo.CurrentCulture,
            "Invalid type for binding. Expected type: {0}. Type passed in: {1}.",
            typeof(SampleProfileUdpBinding).AssemblyQualifiedName,
            binding.GetType().AssemblyQualifiedName));
    }
    SampleProfileUdpBinding udpBinding = (SampleProfileUdpBinding)binding;

    udpBinding.OrderedSession = this.OrderedSession;
    udpBinding.ReliableSessionEnabled = this.ReliableSessionEnabled;
    udpBinding.SessionInactivityTimeout = this.SessionInactivityTimeout;
    if (this.ClientBaseAddress != null)
        udpBinding.ClientBaseAddress = ClientBaseAddress;
}

このハンドラーを構成システムに登録するには、関連する構成ファイルに次のセクションを追加します。

<configuration>
  <configSections>
     <sectionGroup name="system.serviceModel">
        <sectionGroup name="bindings">
          <section name="sampleProfileUdpBinding" type="Microsoft.ServiceModel.Samples.SampleProfileUdpBindingCollectionElement, UdpTransport" />
        </sectionGroup>
     </sectionGroup>
  </configSections>
</configuration>

その後、serviceModel 構成セクションから参照できます。

<configuration>
  <system.serviceModel>
    <client>
      <endpoint configurationName="calculator"
                address="soap.udp://localhost:8001/"
                bindingConfiguration="CalculatorServer"
                binding="sampleProfileUdpBinding"
                contract= "Microsoft.ServiceModel.Samples.ICalculatorContract">
      </endpoint>
    </client>
  </system.serviceModel>
</configuration>

UDP テスト サービスとクライアント

このサンプル トランスポートを使用するためのテスト コードは、UdpTestService ディレクトリと UdpTestClient ディレクトリで使用できます。 サービス コードは 2 つのテストで構成されます。1 つのテストはコードからバインドとエンドポイントを設定し、もう 1 つは構成を介して行います。 両方のテストで 2 つのエンドポイントが使用されます。 1 つのエンドポイントは、trueに設定<>SampleUdpProfileBindingを使用します。 もう 1 つのエンドポイントでは、 UdpTransportBindingElementでカスタム バインドを使用します。 これは、<reliableSession>をfalseに設定してSampleUdpProfileBindingを使用することと同じです。 どちらのテストでも、サービスを作成し、各バインディングのエンドポイントを追加し、サービスを開き、ユーザーが Enter キーを押してからサービスを閉じるのを待ちます。

サービス テスト アプリケーションを起動すると、次の出力が表示されます。

Testing Udp From Code.
Service is started from code...
Press <ENTER> to terminate the service and start service from config...

その後、発行されたエンドポイントに対してテスト クライアント アプリケーションを実行できます。 クライアント テスト アプリケーションは、エンドポイントごとにクライアントを作成し、各エンドポイントに 5 つのメッセージを送信します。 次の出力はクライアント上にあります。

Testing Udp From Imported Files Generated By SvcUtil.
0
3
6
9
12
Press <ENTER> to complete test.

サービスの完全な出力を次に示します。

Service is started from code...
Press <ENTER> to terminate the service and start service from config...
Hello, world!
Hello, world!
Hello, world!
Hello, world!
Hello, world!
   adding 0 + 0
   adding 1 + 2
   adding 2 + 4
   adding 3 + 6
   adding 4 + 8

構成を使用して発行されたエンドポイントに対してクライアント アプリケーションを実行するには、サービスで Enter キーを押し、テスト クライアントをもう一度実行します。 サービスに次の出力が表示されます。

Testing Udp From Config.
Service is started from config...
Press <ENTER> to terminate the service and exit...

クライアントを再度実行すると、上記の結果と同じ結果が生成されます。

Svcutil.exeを使用してクライアント コードと構成を再生成するには、サービス アプリケーションを起動し、サンプルのルート ディレクトリから次の Svcutil.exe を実行します。

svcutil http://localhost:8000/udpsample/ /reference:UdpTransport\bin\UdpTransport.dll /svcutilConfig:svcutil.exe.config

Svcutil.exe では SampleProfileUdpBindingのバインド拡張機能の構成は生成されないため、手動で追加する必要があります。

<configuration>
  <system.serviceModel>
    <extensions>
      <!-- This was added manually because svcutil.exe does not add this extension to the file -->
      <bindingExtensions>
        <add name="sampleProfileUdpBinding" type="Microsoft.ServiceModel.Samples.SampleProfileUdpBindingCollectionElement, UdpTransport" />
      </bindingExtensions>
    </extensions>
  </system.serviceModel>
</configuration>

サンプルを設定、ビルド、実行するには

  1. ソリューションをビルドするには、「 Windows Communication Foundation サンプルのビルド」の手順に従います。

  2. 単一または複数のコンピューター間の構成でサンプルを実行するには、「Windows Communication Foundation Samplesの実行」の手順に従います。

  3. 前述の「UDP テスト サービスとクライアント」セクションを参照してください。