Net.TCP ポート共有のサンプルNet.TCP Port Sharing Sample

TCP/IP プロトコルはポートと呼ばれる 16 ビットの番号を使用して、同じコンピュータ上で実行されている複数のネットワーク アプリケーションへの接続を区別します。The TCP/IP protocol uses a 16-bit number, called a port, to differentiate connections to multiple network applications running on the same machine. アプリケーションがポートをリッスンすると、そのポートのすべての TCP トラフィックがそのアプリケーションに送られます。If an application is listening on a port, then all TCP traffic for that port goes to that application. 他のアプリケーションは、そのポートを同時にリッスンできません。Other applications cannot listen on that port at the same time.

重要

サンプルは、既にコンピューターにインストールされている場合があります。The samples may already be installed on your machine. 続行する前に、次の (既定の) ディレクトリを確認してください。Check for the following (default) directory before continuing.

<InstallDrive>:\WF_WCF_Samples

このディレクトリが存在しない場合は、 Windows Communication Foundation (wcf) および Windows Workflow Foundation (WF) のサンプルの .NET Framework 4 にアクセスして、すべての WINDOWS COMMUNICATION FOUNDATION (wcf) とサンプルをダウンロードして WFWF ください。If this directory does not exist, go to Windows Communication Foundation (WCF) and Windows Workflow Foundation (WF) Samples for .NET Framework 4 to download all Windows Communication Foundation (WCF) and WFWF samples. このサンプルは、次のディレクトリに格納されます。This sample is located in the following directory.

<InstallDrive>:\WF_WCF_Samples\WCF\Basic\Binding\Net\TCP\PortSharing

多くのプロトコルは、使用する標準または既定のポート番号を持っています。Many protocols have a standard or default port number that they use. たとえば、HTTP プロトコルは一般的に TCP ポート 80 を使用します。For example, the HTTP protocol typically uses TCP port 80. インターネット インフォメーション サービス (IIS) には、複数の HTTP アプリケーション間でポートを共有するためのリスナーがあります。Internet Information Services (IIS) has a listener to share a port between multiple HTTP applications. IIS はポートを直接リッスンし、メッセージ ストリーム内の情報に基づいて、そのメッセージを適切なアプリケーションに転送します。IIS listens on the port directly and forwards messages to the appropriate application based on information inside the message stream. これにより、複数の HTTP アプリケーションで、メッセージ受信用のポートの予約が競合することなく同じポート番号を使用できます。This allows multiple HTTP applications to use the same port number without having to compete to reserve the port for receiving messages.

NetTcp ポート共有は、同じように、複数のネットワークアプリケーションが1つのポートを共有できる Windows Communication Foundation (WCF) 機能です。NetTcp Port Sharing is a Windows Communication Foundation (WCF)feature that similarly allows multiple network applications to share a single port. NetTcp ポート共有サービスは net.tcp プロトコルを使用して接続を受け入れ、メッセージの送信先アドレスに基づいてメッセージを転送します。The NetTcp Port Sharing Service accepts connections using the net.tcp protocol and forwards messages based on their destination address.

既定では、NetTcp ポート共有サービスは有効ではありません。The NetTcp Port Sharing Service is not enabled by default. このサンプルを実行する前に、手動でサービスを有効にする必要があります。Before running this sample, you must manually enable the service. 詳細については、「 方法: Net.tcp ポート共有サービスを有効にする」を参照してください。For more information, see How to: Enable the Net.TCP Port Sharing Service. サービスが無効な場合は、サーバー アプリケーションの開始時に例外がスローされます。If the service is disabled, an exception is thrown when the server application is started.

Unhandled Exception: System.ServiceModel.CommunicationException: The TransportManager failed to listen on the supplied URI using the NetTcpPortSharing service: failed to start the service because it is disabled. An administrator can enable it by running 'sc.exe config NetTcpPortSharing start= demand'.. ---> System.InvalidOperationException: Cannot start service NetTcpPortSharing on computer '.'. ---> System.ComponentModel.Win32Exception: The service cannot be started, either because it is disabled or because it has no enabled devices associated with it  

ポート共有をサーバー上で有効にするには、PortSharingEnabled バインディングまたは NetTcpBinding バインディング要素の TcpTransportBindingElement プロパティを設定します。Port sharing is enabled on the server by setting the PortSharingEnabled property of the NetTcpBinding binding or the TcpTransportBindingElement binding element. クライアントは、サーバー上で使用されるポート共有の構成内容を知る必要はありません。The client does not have to know how port sharing has been configured to use it on the server.

ポート共有の有効化Enabling Port Sharing

次のコードでは、サーバー上でのポート共有の有効化を示します。The following code demonstrates enabling port sharing on the server. ランダムな URI パスが含まれる固定ポートで、ICalculator サービスのインスタンスを開始します。It starts an instance of the ICalculator service on a fixed port with a random URI path. 2 つのサービスは同じポートを共有できますが、NetTcp ポート共有サービスが正しいアプリケーションにメッセージをルーティングできるように、これらのエンドポイント アドレスは全体で一意であることが必要です。Even though two services can share the same port, their overall endpoint addresses still must be unique so that the NetTcp Port Sharing Service can route messages to the correct application.

// Configure a binding with TCP port sharing enabled  
NetTcpBinding binding = new NetTcpBinding();  
binding.PortSharingEnabled = true;  
  
// Start a service on a fixed TCP port  
ServiceHost host = new ServiceHost(typeof(CalculatorService));  
ushort salt = (ushort)new Random().Next();  
string address = $"net.tcp://localhost:9000/calculator/{salt}";
host.AddServiceEndpoint(typeof(ICalculator), binding, address);  
host.Open();  

ポート共有を有効にすると、ポート番号の競合を起こすことなく、何度もサービスを実行できます。With port sharing enabled, you can run the service multiple times without having a conflict over the port number. コードを変更してポート共有を無効にした場合、サービスを 2 つ開始すると 2 つ目のサービスが失敗し、AddressAlreadyInUseException が発生します。If you change the code to disable port sharing, starting up two copies of the service results in the second failing with an AddressAlreadyInUseException.

Unhandled Exception: System.ServiceModel.AddressAlreadyInUseException: There is already a listener on IP endpoint 0.0.0.0:9000.  Make sure that you are not trying to use this endpoint multiple times in your application and that there are no other applications listening on this endpoint. ---> System.Net.Sockets.SocketException: Only one usage of each socket address (protocol/network address/port) is normally permitted  

サンプルの実行Running the Sample

テスト クライアントを使用して、ポートを共有しているサービスにメッセージが正しくルーティングされていることを確認できます。You can use the test client to check that messages are correctly routed to services sharing the port.

class client  
{  
   static void Main(string[] args)  
   {  
      Console.Write("Enter the service number to test: ");  
      ushort salt = ushort.Parse(Console.ReadLine());  
      string address = $"net.tcp://localhost:9000/calculator/{salt}";
      ChannelFactory<ICalculator> factory = new ChannelFactory<ICalculator>(new NetTcpBinding());  
      ICalculator proxy = factory.CreateChannel(new EndpointAddress(address));  
  
      // Call the Add service operation.  
      double value1 = 100.00D;  
      double value2 = 15.99D;  
      double result = proxy.Add(value1, value2);  
      Console.WriteLine("Add({0},{1}) = {2}", value1, value2, result);  
  
      // Call the Subtract service operation.  
      value1 = 145.00D;  
      value2 = 76.54D;  
      result = proxy.Subtract(value1, value2);  
      Console.WriteLine("Subtract({0},{1}) = {2}", value1, value2, result);  
  
      // Call the Multiply service operation.  
      value1 = 9.00D;  
      value2 = 81.25D;  
      result = proxy.Multiply(value1, value2);  
      Console.WriteLine("Multiply({0},{1}) = {2}", value1, value2, result);  
  
      // Call the Divide service operation.  
      value1 = 22.00D;  
      value2 = 7.00D;  
      result = proxy.Divide(value1, value2);  
      Console.WriteLine("Divide({0},{1}) = {2}", value1, value2, result);  
  
      Console.WriteLine();  
      Console.WriteLine("Press <ENTER> to terminate client.");  
      Console.ReadLine();  
  
      factory.Close();  
   }  
}  

サービスの各インスタンスは、一意の番号とアドレスを出力します。Each instance of the service prints out its unique number and address. たとえば、service.exe を実行すると、次のテキストが表示されます。For instance, you may see the following text when you run service.exe.

Service #4381 listening on net.tcp://localhost:9000/calculator/4381.  
Press <ENTER> to terminate service.  

client.exe を実行する際に、ここに表示されるサービス番号を入力します。Enter the service number you see here when you run client.exe.

Enter the service number to test: 4381  
Add(100,15.99) = 115.99  
Subtract(145,76.54) = 68.46  
Multiply(9,81.25) = 731.25  
Divide(22,7) = 3.14285714285714  
  
Press <ENTER> to terminate client.  

このサンプルは、クライアントが使用する生成アドレスを変更することにより、複数コンピュータの構成で実行できます。This sample can be run in a cross-machine configuration by changing the generated address that the client uses. Client.cs で、エンドポイント アドレスの書式文字列をサービスの新しいアドレスに合わせます。In the Client.cs, change the endpoint address format string to match the new address of your service. "localhost" への参照をすべてサーバー コンピュータの IP アドレスに置き換えます。Replace any references to "localhost" with the IP address of the server machine. この変更を行った後に、サンプルを再コンパイルする必要があります。You must recompile the sample after making this change.

サンプルをセットアップ、ビルド、および実行するにはTo set up, build, and run the sample

  1. 次のコマンドを使用して、ASP.NET 4.0 をインストールします。Install ASP.NET 4.0 using the following command.

    %windir%\Microsoft.NET\Framework\v4.0.XXXXX\aspnet_regiis.exe /i /enable  
    
  2. Windows Communication Foundation サンプルの1回限りのセットアップ手順を実行したことを確認します。Ensure that you have performed the One-Time Setup Procedure for the Windows Communication Foundation Samples.

  3. 概要セクションに示したように、NetTcp ポート共有サービスを有効にします。Enable the NetTcp Port Sharing Service as previously described in the introduction section.

  4. ソリューションの C# 版または Visual Basic .NET 版をビルドするには、「 Building the Windows Communication Foundation Samples」の手順に従います。To build the C# or Visual Basic .NET edition of the solution, follow the instructions in Building the Windows Communication Foundation Samples.

  5. サンプルを単一コンピューター構成または複数コンピューター構成で実行するには、「 Windows Communication Foundation サンプルの実行」の手順に従います。To run the sample in a single- or cross-machine configuration, follow the instructions in Running the Windows Communication Foundation Samples. このサンプルを実行するための詳細情報については、前述の「サンプルの実行」を参照してください。Specific details for running this sample are included previously in the Running the Sample section.