简体   繁体   English

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

[英]WCF With NetTCP across machines on the same network

I'm trying to implement some cross process communication that is between multiple computers and one server on the same network. 我正在尝试在同一网络上的多台计算机和一台服务器之间实现一些跨进程通信。 What I'm trying right now is to use WCF with NetTcpBinding, hosted within my application which works on the same machine, but when I try to connect from another machine it throws a SSPI security error. 我现在正在尝试的是使用WCF和NetTcpBinding,我的应用程序托管在同一台机器上,但是当我尝试从另一台机器连接时,它会抛出SSPI安全错误。

I've found lots of examples of doing this cross-machine, but all involve an app.config file which I would REALLY like to avoid. 我发现了很多这样的跨机器的例子,但都涉及到app.config文件,我真的很想避免。 I want to be able to embed this functionality in a DLL that has not other dependencies (ie config files) for which I can just pass into it all of the necessary server addresses, etc and it will work. 我希望能够将此功能嵌入到没有其他依赖项(即配置文件)的DLL中,我可以将其传递给所有必需的服务器地址等,它将起作用。 Is there anyway to setup this security (via the endpoints, etc) purely in code? 无论如何,仅仅在代码中设置此安全性(通过端点等)?

I'm testing this all out with the code below: 我正在用以下代码测试这一切:

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

CLIENT: 客户:

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

Security is normally configured on the binding. 通常在绑定上配置安全性。 You are using NetTcpBinding with its defaults which means that Transport security is enabled. 您正在使用NetTcpBinding及其默认值,这意味着启用了Transport安全性。

On both, server and client, you should assign the NetTcpBinding instance to a local variable so that you can change the security (and possibly other) settings, and then use that variable when calling AddServiceEndpoint or when creating the ChannelFactory . 在服务器和客户端上,您应该将NetTcpBinding实例分配给本地变量,以便您可以更改安全性(可能还有其他)设置,然后在调用AddServiceEndpoint或创建ChannelFactory时使用该变量。

Sample: 样品:

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

This is probably an issue with the SPN that your service is running under. 这可能是您的服务正在运行的SPN的问题。 It's most likely a machine account instead of a domain account. 它很可能是一个机器帐户而不是域帐户。 There's more information in this thread . 这个帖子中有更多信息。

UPDATE: There's information in there about setting the SPN programmatically, but it's buried a few clicks in... here's a direct link (see the last section of the page). 更新:有关于以编程方式设置SPN的信息,但它只是点击了几下...这里是一个直接链接 (参见页面的最后一部分)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM