Udostępnij za pośrednictwem


Przykład współużytkowania portów Net.TCP

W tym artykule opisano przykład PortSharing.

Protokół TCP/IP używa 16-bitowej liczby nazywanej portem, aby odróżnić połączenia z wieloma aplikacjami sieciowymi uruchomionymi na tym samym komputerze. Jeśli aplikacja nasłuchuje na porcie, cały ruch TCP dla tego portu przechodzi do tej aplikacji. Inne aplikacje nie mogą nasłuchiwać tego portu w tym samym czasie.

Wiele protokołów ma standardowy lub domyślny numer portu, którego używają. Na przykład protokół HTTP zazwyczaj używa portu TCP 80. Usługi Internet Information Services (IIS) mają odbiornik do udostępniania portu między wieloma aplikacjami HTTP. Usługi IIS nasłuchują bezpośrednio na porcie i przekazują komunikaty do odpowiedniej aplikacji na podstawie informacji wewnątrz strumienia komunikatów. Dzięki temu wiele aplikacji HTTP może używać tego samego numeru portu bez konieczności konkurowania w celu zarezerwowania portu na potrzeby odbierania komunikatów.

Udostępnianie portów NetTcp to funkcja programu Windows Communication Foundation (WCF), która podobnie umożliwia wielu aplikacjom sieciowym współużytkowanie jednego portu. Usługa udostępniania portów NetTcp akceptuje połączenia przy użyciu protokołu net.tcp i przekazuje komunikaty na podstawie ich adresu docelowego.

Usługa udostępniania portów NetTcp nie jest domyślnie włączona. Przed uruchomieniem tego przykładu należy ręcznie włączyć usługę. Aby uzyskać więcej informacji, zobacz Instrukcje: włączanie usługi udostępniania portów Net.TCP. Jeśli usługa jest wyłączona, podczas uruchamiania aplikacji serwera jest zgłaszany wyjątek.

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

Udostępnianie portów jest włączone na serwerze przez ustawienie PortSharingEnabled właściwości NetTcpBinding powiązania lub TcpTransportBindingElement elementu powiązania. Klient nie musi wiedzieć, jak skonfigurowano udostępnianie portów do korzystania z niego na serwerze.

Włączanie udostępniania portów

Poniższy kod przedstawia włączanie udostępniania portów na serwerze. Uruchamia wystąpienie ICalculator usługi na stałym porcie ze losową ścieżką identyfikatora URI. Mimo że dwie usługi mogą współdzielić ten sam port, ich ogólne adresy końcowe nadal muszą być unikatowe, aby usługa udostępniania portów NetTcp mogła kierować komunikaty do odpowiedniej aplikacji.

// 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();

Dzięki włączeniu udostępniania portów można wielokrotnie uruchamiać usługę bez konfliktu z numerem portu. Jeśli zmienisz kod tak, aby wyłączyć udostępnianie portów, uruchomienie dwóch kopii usługi spowoduje niepowodzenie drugiego wystąpienia błędu 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

Uruchamianie przykładu

Możesz użyć klienta testowego, aby sprawdzić, czy komunikaty są prawidłowo kierowane do usług współużytkujących 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();
   }
}

Każde wystąpienie usługi wyświetla unikatowy numer i adres. Na przykład podczas uruchamiania service.exe może zostać wyświetlony następujący tekst.

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

Wprowadź numer usługi widoczny tutaj po uruchomieniu 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.

Ten przykład można uruchomić w konfiguracji między maszynami, zmieniając wygenerowany adres używany przez klienta. W Client.cs zmień ciąg formatu adresu punktu końcowego, aby był zgodny z nowym adresem usługi. Zastąp wszystkie odwołania do "localhost" adresem IP maszyny serwera. Po wprowadzeniu tej zmiany należy ponownie skompilować przykład.

Aby skonfigurować, skompilować i uruchomić przykład

  1. Zainstaluj ASP.NET 4.0 przy użyciu następującego polecenia.

    %windir%\Microsoft.NET\Framework\v4.0.XXXXX\aspnet_regiis.exe /i /enable
    
  2. Upewnij się, że wykonano procedurę instalacji jednorazowej dla przykładów programu Windows Communication Foundation.

  3. Włącz usługę udostępniania portów NetTcp zgodnie z opisem w sekcji wprowadzenia.

  4. Aby skompilować wersję rozwiązania w języku C# lub Visual Basic .NET, postępuj zgodnie z instrukcjami w temacie Building the Windows Communication Foundation Samples (Tworzenie przykładów programu Windows Communication Foundation).

  5. Aby uruchomić przykład w konfiguracji pojedynczej lub między maszynami, postępuj zgodnie z instrukcjami w temacie Uruchamianie przykładów programu Windows Communication Foundation. Szczegółowe informacje dotyczące uruchamiania tego przykładu znajdują się wcześniej w sekcji Uruchamianie przykładu.