简体   繁体   中英

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.

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. 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. 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.

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 .

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. 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).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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