Partilhar via


Exemplo de compartilhamento de porta Net.TCP

Este artigo descreve o exemplo PortSharing.

O protocolo TCP/IP usa um número de 16 bits, chamado de porta, para diferenciar conexões com vários aplicativos de rede em execução na mesma máquina. Se um aplicativo estiver escutando em uma porta, todo o tráfego TCP dessa porta irá para esse aplicativo. Outros aplicativos não podem escutar nessa porta ao mesmo tempo.

Muitos protocolos têm um número de porta padrão ou padrão que eles usam. Por exemplo, o protocolo HTTP normalmente usa a porta TCP 80. O IIS (Serviços de Informações da Internet) tem um ouvinte para compartilhar uma porta entre vários aplicativos HTTP. O IIS escuta diretamente na porta e encaminha mensagens para o aplicativo apropriado com base nas informações dentro do fluxo de mensagens. Isso permite que vários aplicativos HTTP usem o mesmo número de porta sem ter que competir para reservar a porta para receber mensagens.

O Compartilhamento de Porta NetTcp é um recurso do Windows Communication Foundation (WCF) que, da mesma forma, permite que vários aplicativos de rede compartilhem uma única porta. O Serviço de Compartilhamento de Porta NetTcp aceita conexões usando o protocolo net.tcp e encaminha mensagens com base em seu endereço de destino.

O Serviço de Compartilhamento de Porta NetTcp não está habilitado por padrão. Antes de executar este exemplo, você deve habilitar manualmente o serviço. Para obter mais informações, consulte Como habilitar o serviço de compartilhamento de porta Net.TCP. Se o serviço estiver desabilitado, uma exceção será lançada quando o aplicativo de servidor for iniciado.

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

O compartilhamento de portas é habilitado no servidor definindo a PortSharingEnabled propriedade da associação ou o TcpTransportBindingElement elemento de NetTcpBinding ligação. O cliente não precisa saber como o compartilhamento de porta foi configurado para usá-lo no servidor.

Ativando o compartilhamento de portas

O código a seguir demonstra a habilitação do compartilhamento de portas no servidor. Ele inicia uma instância do ICalculator serviço em uma porta fixa com um caminho de URI aleatório. Embora dois serviços possam compartilhar a mesma porta, seus endereços de ponto de extremidade gerais ainda devem ser exclusivos para que o Serviço de Compartilhamento de Porta NetTcp possa rotear mensagens para o aplicativo correto.

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

Com o compartilhamento de porta habilitado, você pode executar o serviço várias vezes sem ter um conflito sobre o número da porta. Se você alterar o código para desabilitar o compartilhamento de portas, a inicialização de duas cópias do serviço resultará na segunda falha com um AddressAlreadyInUseExceptionarquivo .

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

Executando o exemplo

Você pode usar o cliente de teste para verificar se as mensagens são roteadas corretamente para serviços que compartilham a porta.

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

Cada instância do serviço imprime seu número e endereço exclusivos. Por exemplo, você pode ver o seguinte texto quando executar service.exe.

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

Introduza o número de serviço que vê aqui quando executa 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.

Este exemplo pode ser executado em uma configuração entre máquinas alterando o endereço gerado que o cliente usa. No Client.cs, altere a cadeia de caracteres do formato do endereço do ponto de extremidade para corresponder ao novo endereço do seu serviço. Substitua quaisquer referências a "localhost" pelo endereço IP da máquina do servidor. Você deve recompilar o exemplo depois de fazer essa alteração.

Para configurar, compilar e executar o exemplo

  1. Instale o ASP.NET 4.0 usando o seguinte comando.

    %windir%\Microsoft.NET\Framework\v4.0.XXXXX\aspnet_regiis.exe /i /enable
    
  2. Certifique-se de ter executado o procedimento de instalação única para os exemplos do Windows Communication Foundation.

  3. Habilite o Serviço de Compartilhamento de Porta NetTcp conforme descrito anteriormente na seção de introdução.

  4. Para criar a edição C# ou Visual Basic .NET da solução, siga as instruções em Criando os exemplos do Windows Communication Foundation.

  5. Para executar o exemplo em uma configuração de máquina única ou cruzada, siga as instruções em Executando os exemplos do Windows Communication Foundation. Detalhes específicos para executar este exemplo são incluídos anteriormente na seção Executando o exemplo.