UDP トランスポートのサンプルでは、カスタム Windows Communication Foundation (WCF) トランスポートとして UDP ユニキャストとマルチキャストを実装する方法を示します。 このサンプルでは、チャネル フレームワークを使用し、WCF のベスト プラクティスに従って、WCF でカスタム トランスポートを作成するための推奨手順について説明します。 カスタム トランスポートを作成する手順は次のとおりです。
ChannelFactory と ChannelListener がサポートするチャネル のメッセージ交換パターン (IOutputChannel、IInputChannel、IDuplexChannel、IRequestChannel、または IReplyChannel) を決定します。 次に、これらのインターフェイスのセッションフル バリエーションをサポートするかどうかを決定します。
Message Exchange パターンをサポートするチャネル ファクトリとリスナーを作成します。
ネットワーク固有の例外が、 CommunicationExceptionの適切な派生クラスに正規化されていることを確認します。
チャネル スタックにカスタム トランスポートを追加する <binding> 要素を追加します。 詳細については、「 バインド要素の追加」を参照してください。
新しいバインド要素を構成システムに公開するバインド要素拡張セクションを追加します。
他のエンドポイントと機能を通信するためのメタデータ拡張機能を追加します。
適切に定義されたプロファイルに従ってバインド要素のスタックを事前に構成するバインディングを追加します。 詳細については、「 標準バインディングの追加」を参照してください。
バインド セクションとバインド構成要素を追加して、バインドを構成システムに公開します。 詳細については、「 構成サポートの追加」を参照してください。
メッセージ交換パターン
カスタム トランスポートを作成する最初の手順は、トランスポートに必要なメッセージ交換パターン (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 には、通信に使用される IChannel、 IChannelFactory、 IChannelListener などのオブジェクトのライフサイクルを管理するために使用される共通のステート マシンがあります。 これらの通信オブジェクトが存在できる状態は 5 つあります。 これらの状態は、 CommunicationState 列挙体によって表され、次のようになります。
作成済み: これは、最初にインスタンス化されたときの ICommunicationObject の状態です。 この状態では入出力 (I/O) は発生しません。
開く: Open が呼び出されると、オブジェクトはこの状態に遷移します。 この時点で、プロパティは変更不可になり、入力/出力を開始できます。 この遷移は、Created 状態からのみ有効です。
開かれた: オブジェクトは、開いているプロセスが完了すると、この状態に遷移します。 この遷移は、開始状態からのみ有効です。 この時点で、オブジェクトは完全に転送に使用できます。
Closing: 正常なシャットダウンのために Close が呼び出されると、オブジェクトはこの状態に遷移します。 この遷移は、Opened 状態からのみ有効です。
Closed: Closed 状態のオブジェクトは使用できなくなりました。 一般に、ほとんどの構成は検査のために引き続きアクセスできますが、通信は行われません。 この状態は破棄と同じです。
Faulted: Faulted 状態では、オブジェクトは検査にアクセスできますが、使用できなくなります。 回復不可能なエラーが発生すると、オブジェクトはこの状態に遷移します。 この状態からの唯一の有効な遷移は、
Closed
状態です。
状態遷移ごとに発生するイベントがあります。 Abort メソッドはいつでも呼び出すことができます。これにより、オブジェクトは現在の状態から Closed 状態に直ちに遷移します。 Abortを呼び出すと、未完了の作業が終了します。
チャネル ファクトリとチャネル リスナー
カスタム トランスポートを記述する次の手順は、クライアント チャネルとサービス チャネルのIChannelListenerのIChannelFactoryの実装を作成することです。 チャネル レイヤーは、チャネルの構築にファクトリ パターンを使用します。 WCF には、このプロセスの基本クラス ヘルパーが用意されています。
CommunicationObject クラスは、ICommunicationObjectを実装し、手順 2 で説明したステート マシンを適用します。
ChannelManagerBase クラスはCommunicationObjectを実装し、ChannelFactoryBaseとChannelListenerBaseの統合基本クラスを提供します。 ChannelManagerBase クラスは、ChannelBaseを実装する基底クラスである IChannel と組み合わせて動作します。
ChannelFactoryBase クラスは、ChannelManagerBaseとIChannelFactoryを実装し、
CreateChannel
オーバーロードを 1 つのOnCreateChannel
抽象メソッドに統合します。ChannelListenerBase クラスは、IChannelListenerを実装します。 基本状態管理を行います。
このサンプルでは、ファクトリ実装は UdpChannelFactory.cs に含まれており、リスナーの実装は UdpChannelListener.cs に含まれています。 IChannel実装は、UdpOutputChannel.csとUdpInputChannel.csにあります。
UDP チャネル ファクトリ
UdpChannelFactory
は ChannelFactoryBaseから派生します。 このサンプルでは、メッセージ エンコーダーのメッセージ バージョンへのアクセスを提供するために、 GetProperty をオーバーライドします。 また、ステート マシンの遷移時にBufferManagerのインスタンスを破棄できるように、このサンプルはOnCloseをオーバーライドします。
UDP 出力チャネル
UdpOutputChannel
はIOutputChannelを実装します。 コンストラクターは、引数を検証し、渡された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 エクスポート
アドレス指定情報をエクスポートするために、 UdpTransportBindingElement
は IWsdlExportExtension
インターフェイスを実装します。
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 つのオプションがあります。
/SvcutilConfig:<file>を使用して、構成ファイル Svcutil.exe ポイントします。
設定セクションを 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 つのオプションがあります。
/SvcutilConfig:<file>を使用して、構成ファイル Svcutil.exe ポイントします。
設定セクションを Svcutil.exe.config と同じディレクトリに追加します Svcutil.exe。
標準バインドの追加
バインド要素は、次の 2 つの方法で使用できます。
カスタム バインドを使用する: カスタム バインドを使用すると、ユーザーは任意のバインド要素のセットに基づいて独自のバインドを作成できます。
バインディング要素を含むシステム提供のバインディングを使用する。 WCF には、
BasicHttpBinding
、NetTcpBinding
、WsHttpBinding
など、システム定義のバインドが多数用意されています。 これらの各バインディングは、明確に定義されたプロファイルに関連付けられます。
このサンプルでは、Bindingから派生したSampleProfileUdpBinding
にプロファイル バインドを実装しています。
SampleProfileUdpBinding
には、UdpTransportBindingElement
、TextMessageEncodingBindingElement CompositeDuplexBindingElement
、ReliableSessionBindingElement
という最大 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 と WsdlImporter
が SampleProfileUdpBinding
をインポートできるようにするために、 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 つ目は、UdpTransportBindingElement
のBindingElementExtensionElement
です。 これは、 CustomBinding
実装がバインディング要素を参照できるようにするためです。 2 つ目は、SampleProfileUdpBinding
のConfiguration
です。
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
バインドからマップする関数があります。 最後に、次のサンプル コードに示すように、SampleProfileUdpBinding
のOnApplyConfiguration
メソッドをオーバーライドします。
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>
サンプルを設定、ビルド、実行するには
ソリューションをビルドするには、「 Windows Communication Foundation サンプルのビルド」の手順に従います。
単一または複数のコンピューター間の構成でサンプルを実行するには、「Windows Communication Foundation Samplesの実行」の手順に従います。
前述の「UDP テスト サービスとクライアント」セクションを参照してください。