WCF使用NetTCP跨越同一网络上的计算机

时间:2011-08-01 20:25:18

标签: c# wcf nettcpbinding

我正在尝试在同一网络上的多台计算机和一台服务器之间实现一些跨进程通信。我现在正在尝试的是使用WCF和NetTcpBinding,它在我的应用程序中托管,它在同一台机器上运行,但是当我尝试从另一台机器连接时,它会抛出SSPI安全错误。

我发现很多这样的跨机器的例子,但都涉及app.config文件,我真的很想避免。我希望能够将此功能嵌入到没有其他依赖项(即配置文件)的DLL中,我可以将所有必需的服务器地址等传递给它,它将起作用。无论如何都是纯粹在代码中设置这种安全性(通过端点等)?

我正在使用以下代码对此进行全面测试:

SERVER:

using System;
using System.ServiceModel;

namespace WCFServer
{
  [ServiceContract]
  public interface IStringReverser
  {
    [OperationContract]
    string ReverseString(string value);
  }

  public class StringReverser : IStringReverser
  {
    public string ReverseString(string value)
    {
      char[] retVal = value.ToCharArray();
      int idx = 0;
      for (int i = value.Length - 1; i >= 0; i--)
        retVal[idx++] = value[i];

      string result = new string(retVal);
      Console.WriteLine(value + " -> " + result);
      return result;
    }
  }

  class Program
  {
    static void Main(string[] args)
    {
        var uri = "net.tcp://" + System.Net.Dns.GetHostName() + ":9985";
        Console.WriteLine("Opening connection on: " + uri);

      using (ServiceHost host = new ServiceHost(
        typeof(StringReverser),
        new Uri[]{
          new Uri("net.tcp://" + System.Net.Dns.GetHostName() + ":9985")
        }))
      {
        host.AddServiceEndpoint(typeof(IStringReverser),
          new NetTcpBinding(),
          "TcpReverse");

        host.Open();

        Console.WriteLine("Service is available. " +  
          "Press <ENTER> to exit.");
        Console.ReadLine();

        host.Close();
      }
    }
  }
}

客户端:

using System;
using System.ServiceModel;
using System.ServiceModel.Channels;

namespace WCFClient
{
  [ServiceContract]
  public interface IStringReverser
  {
    [OperationContract]
    string ReverseString(string value);
  }

  class Program
  {
    static void Main(string[] args)
    {
        var ep = "net.tcp://SERVER:9985/TcpReverse";
      ChannelFactory<IStringReverser> pipeFactory =
        new ChannelFactory<IStringReverser>(
          new NetTcpBinding(),
          new EndpointAddress(
            ep));

      IStringReverser pipeProxy =
        pipeFactory.CreateChannel();

      Console.WriteLine("Connected to: " + ep);
      while (true)
      {
        string str = Console.ReadLine();
        Console.WriteLine("pipe: " + 
          pipeProxy.ReverseString(str));
      }
    }
  }
}

2 个答案:

答案 0 :(得分:5)

通常在绑定上配置安全性。您正在使用NetTcpBinding及其默认值,这意味着已启用Transport安全性。

在服务器和客户端上,您应该将NetTcpBinding实例分配给本地变量,以便您可以更改安全性(可能还有其他)设置,然后在调用AddServiceEndpoint时使用该变量或者在创建ChannelFactory

样品:

var binding = new NetTcpBinding();
// disable security:
binding.Security.Mode = SecurityMode.None;

答案 1 :(得分:1)

这可能是您的服务正在运行的SPN的问题。它很可能是一个机器帐户而不是域帐户。有更多信息in this thread

更新:这里有关于以编程方式设置SPN的信息,但它只是点击了几下...这里是direct link(参见页面的最后一部分)。