Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/334.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 自托管WCF可以连接到本地主机,但可以';t连接远程_C#_Wcf_Wcf Security_Self Host Webapi - Fatal编程技术网

C# 自托管WCF可以连接到本地主机,但可以';t连接远程

C# 自托管WCF可以连接到本地主机,但可以';t连接远程,c#,wcf,wcf-security,self-host-webapi,C#,Wcf,Wcf Security,Self Host Webapi,我有一个自托管的C#WCF.Net 4.6.1 Windows服务,它与另一个自托管的WCF服务进行通信。当两个服务都在同一台服务器上时,这种方法可以很好地工作。但是,当我将服务器移动到另一台计算机时,会出现以下错误: System.ServiceModel.CommunicationException:套接字连接已中止。这可能是由于处理消息时出错、远程主机超过接收超时或基础网络资源问题造成的。这两台计算机上都没有运行防火墙,我在使用(在应用程序中使用net.tcp)时收到响应 客户端app.c

我有一个自托管的C#WCF.Net 4.6.1 Windows服务,它与另一个自托管的WCF服务进行通信。当两个服务都在同一台服务器上时,这种方法可以很好地工作。但是,当我将服务器移动到另一台计算机时,会出现以下错误:

System.ServiceModel.CommunicationException:套接字连接已中止。这可能是由于处理消息时出错、远程主机超过接收超时或基础网络资源问题造成的。这两台计算机上都没有运行防火墙,我在使用(在应用程序中使用net.tcp)时收到响应

客户端
app.config

<bindings>
    <basicHttpBinding>
        <binding name="BasicHttpBinding_IeTutorMessage" />
    </basicHttpBinding>
    <netTcpBinding>
        <binding name="NetTcpBinding_IeTutorMessage" />
    </netTcpBinding>
</bindings>

<client>
    <endpoint name="BasicHttpBinding_IeTutorMessage" 
        address="http://localhost:6253/eTutorWcfService" 
        binding="basicHttpBinding"
        bindingConfiguration="BasicHttpBinding_IeTutorMessage" 
        contract="eTutorServiceReference.IeTutorMessage" />
    <endpoint name="NetTcpBinding_IeTutorMessage"
        address="net.tcp://localhost:6254/eTutorWcfService"
        binding="netTcpBinding"   
        bindingConfiguration="NetTcpBinding_IeTutorMessage"
        contract="eTutorServiceReference.IeTutorMessage" >
        <identity>
            <servicePrincipalName value = ""/>
        </identity>
    </endpoint>
</client>
<services>
    <service name="eTutorServer.eTutorWcfService" 
             behaviorConfiguration="myeTutorServiceBehavior">
        <host>
            <baseAddresses>
                <add baseAddress="http://localhost:6253/eTutorWcfService"/>
                <add baseAddress="net.tcp://localhost:6254/eTutorWcfService"/>
            </baseAddresses>
        </host>
        <endpoint  
            address="http://localhost:6253/eTutorWcfService" 
            binding="basicHttpBinding" 
            contract="eTutorServer.IeTutorMessage" />
        <endpoint 
            address="net.tcp://localhost:6254/eTutorWcfService" 
            binding="netTcpBinding" 
            contract="eTutorServer.IeTutorMessage" />
        <endpoint 
            address="mex" 
            binding="mexHttpBinding" 
            contract="IMetadataExchange"/>
        <endpoint 
            address="mex" 
            binding="mexTcpBinding" 
            contract="IMetadataExchange"/>
    </service>
</services>
<behaviors>
    <serviceBehaviors>
        <behavior name="myeTutorServiceBehavior">
            <serviceMetadata httpGetEnabled="true"/>
        </behavior>
    </serviceBehaviors>
</behaviors>
客户端代码:

EndpointAddress address = new EndpointAddress("net.tcp://" + eTutorServiceIp + ":6254/eTutorWcfService");
eTutorServiceReference.IeTutorMessageClient client = new eTutorServiceReference.IeTutorMessageClient("NetTcpBinding_IeTutorMessage", address);

try
{
    rtn = client.eTutorMessage(itm);
    client.Close();
}

当客户端尝试连接时,服务器的输出窗口会显示一个
SecurityTokenValidationException
,但我不确定该怎么做,或者它是否意味着相关的内容。我确信这与安全性有关,但我不知道在哪里添加什么。

我添加了以下代码,它可以工作:

client.ClientCredentials.Windows.ClientCredential.UserName = runAs;
client.ClientCredentials.Windows.ClientCredential.Password = runAsPassword;
client.ClientCredentials.Windows.ClientCredential.Domain = runAsDomain;
但是,我希望在没有安全性的情况下执行此操作,因为它将被放置在多个服务器上,而这些服务器都没有公共IP。我试图添加到绑定中,但在客户端上它不是有效的节点,在服务器上,它会阻止服务启动。我试图将以下代码添加到服务器,但它无法打开ServiceHost:

serviceHost.AddServiceEndpoint(typeof(eTutorWcfService), new NetTcpBinding(SecurityMode.None), "");

我可以接受这一点,但我很想知道如何在没有安全性的情况下做到这一点。

首先,Nettcpbinding使用传输安全模式,默认情况下使用windows凭据对客户端进行身份验证。

然后,当我们更改服务器配置并重新托管服务时,我们应该在调用它时重新生成客户机代理类。此外,我们可能需要更改客户端配置中的端点地址,因为本地主机是默认生成的

我可以接受,但我真的很想知道怎么做 没有安全

最后,当我们将安全性更改为“无”时,客户端不需要提供凭据来调用服务。我建议您重新托管服务并重新生成客户端代理类。我做了一个演示,希望对你有用

服务器端(控制台应用程序)

class Program
    {
        static void Main(string[] args)
        {
            using (ServiceHost sh=new ServiceHost(typeof(MyService)))
            {
                sh.Opened += delegate
                {
                    Console.WriteLine("Service is ready......");
                };
                sh.Closed += delegate
                {
                    Console.WriteLine("Service is closed");
                };
                sh.Open();
                Console.ReadLine();
                sh.Close();

            }
        }
    }
    [ServiceContract]
    public interface IService
    {
        [OperationContract]
        string SayHello();
    }
    public class MyService : IService
    {
        public string SayHello()
        {
            return "Hello Stranger";
        }
}
<system.serviceModel>
    <services>
      <service behaviorConfiguration="Service1Behavior" name="VM1.MyService">
        <endpoint address="" binding="netTcpBinding" bindingConfiguration="mybinding" contract="VM1.IService" >
        </endpoint>
        <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange"/>
        <host>
          <baseAddresses>
            <add baseAddress="net.tcp://localhost:13007/"/>
          </baseAddresses>
        </host>
      </service>
    </services>
    <bindings>
      <netTcpBinding>
        <binding name="mybinding">
          <security mode="None">
          </security>
        </binding>
      </netTcpBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior name="Service1Behavior">
          <serviceMetadata />
          <serviceDebug includeExceptionDetailInFaults="False"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
ServiceReference1.ServiceClient client = new ServiceReference1.ServiceClient();
            try
            {
                Console.WriteLine(client.SayHello());
            }
            catch (Exception)
            {

                throw;
            }
    <system.serviceModel>
        <bindings>
            <netTcpBinding>
                <binding name="NetTcpBinding_IService">
                    <security mode="None" />
                </binding>
            </netTcpBinding>
        </bindings>
        <client>
<!--we may need to change the generated endpoint address to autual server IP address.-->
            <endpoint address="net.tcp://10.157.13.69:13007/" binding="netTcpBinding"
                bindingConfiguration="NetTcpBinding_IService" contract="ServiceReference1.IService"
                name="NetTcpBinding_IService" />
        </client>
</system.serviceModel>
App.config

class Program
    {
        static void Main(string[] args)
        {
            using (ServiceHost sh=new ServiceHost(typeof(MyService)))
            {
                sh.Opened += delegate
                {
                    Console.WriteLine("Service is ready......");
                };
                sh.Closed += delegate
                {
                    Console.WriteLine("Service is closed");
                };
                sh.Open();
                Console.ReadLine();
                sh.Close();

            }
        }
    }
    [ServiceContract]
    public interface IService
    {
        [OperationContract]
        string SayHello();
    }
    public class MyService : IService
    {
        public string SayHello()
        {
            return "Hello Stranger";
        }
}
<system.serviceModel>
    <services>
      <service behaviorConfiguration="Service1Behavior" name="VM1.MyService">
        <endpoint address="" binding="netTcpBinding" bindingConfiguration="mybinding" contract="VM1.IService" >
        </endpoint>
        <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange"/>
        <host>
          <baseAddresses>
            <add baseAddress="net.tcp://localhost:13007/"/>
          </baseAddresses>
        </host>
      </service>
    </services>
    <bindings>
      <netTcpBinding>
        <binding name="mybinding">
          <security mode="None">
          </security>
        </binding>
      </netTcpBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior name="Service1Behavior">
          <serviceMetadata />
          <serviceDebug includeExceptionDetailInFaults="False"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
ServiceReference1.ServiceClient client = new ServiceReference1.ServiceClient();
            try
            {
                Console.WriteLine(client.SayHello());
            }
            catch (Exception)
            {

                throw;
            }
    <system.serviceModel>
        <bindings>
            <netTcpBinding>
                <binding name="NetTcpBinding_IService">
                    <security mode="None" />
                </binding>
            </netTcpBinding>
        </bindings>
        <client>
<!--we may need to change the generated endpoint address to autual server IP address.-->
            <endpoint address="net.tcp://10.157.13.69:13007/" binding="netTcpBinding"
                bindingConfiguration="NetTcpBinding_IService" contract="ServiceReference1.IService"
                name="NetTcpBinding_IService" />
        </client>
</system.serviceModel>
App.config

class Program
    {
        static void Main(string[] args)
        {
            using (ServiceHost sh=new ServiceHost(typeof(MyService)))
            {
                sh.Opened += delegate
                {
                    Console.WriteLine("Service is ready......");
                };
                sh.Closed += delegate
                {
                    Console.WriteLine("Service is closed");
                };
                sh.Open();
                Console.ReadLine();
                sh.Close();

            }
        }
    }
    [ServiceContract]
    public interface IService
    {
        [OperationContract]
        string SayHello();
    }
    public class MyService : IService
    {
        public string SayHello()
        {
            return "Hello Stranger";
        }
}
<system.serviceModel>
    <services>
      <service behaviorConfiguration="Service1Behavior" name="VM1.MyService">
        <endpoint address="" binding="netTcpBinding" bindingConfiguration="mybinding" contract="VM1.IService" >
        </endpoint>
        <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange"/>
        <host>
          <baseAddresses>
            <add baseAddress="net.tcp://localhost:13007/"/>
          </baseAddresses>
        </host>
      </service>
    </services>
    <bindings>
      <netTcpBinding>
        <binding name="mybinding">
          <security mode="None">
          </security>
        </binding>
      </netTcpBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior name="Service1Behavior">
          <serviceMetadata />
          <serviceDebug includeExceptionDetailInFaults="False"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
ServiceReference1.ServiceClient client = new ServiceReference1.ServiceClient();
            try
            {
                Console.WriteLine(client.SayHello());
            }
            catch (Exception)
            {

                throw;
            }
    <system.serviceModel>
        <bindings>
            <netTcpBinding>
                <binding name="NetTcpBinding_IService">
                    <security mode="None" />
                </binding>
            </netTcpBinding>
        </bindings>
        <client>
<!--we may need to change the generated endpoint address to autual server IP address.-->
            <endpoint address="net.tcp://10.157.13.69:13007/" binding="netTcpBinding"
                bindingConfiguration="NetTcpBinding_IService" contract="ServiceReference1.IService"
                name="NetTcpBinding_IService" />
        </client>
</system.serviceModel>


如果有什么我可以帮忙的,请随时告诉我。

本地主机在两台电脑上的配置可能不同。检查主机文件:C:\Windows\System32\Drivers\etc\hosts在任一台电脑上的主机文件中都没有条目。使用诸如wireshark或fiddler之类的嗅探器,比较工作电脑和非工作电脑上的结果。查看http响应状态以看看你是否完成了200次。还要检查TCP以查看您是否得到[FIN],它会终止指示完成的TCP连接。可能您在客户端配置中输入的
securitytokenvalidationexception
有关。我不知道,为什么它会出现在配置中。在标识上,它会在某个时候自动添加“msi/steve”(主机名/用户)。我已经取出了值和节点,但是得到了相同的错误。