0

I have a self-hosted C# WCF .Net 4.6.1 Windows service that communicates with another self-hosted WCF service. This works fine when both services are on the same server. However, when I move the server to another computer, I get this error:

System.ServiceModel.CommunicationException: The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. There are no firewalls running on either computer and I get a response when using http://192.168.1.129:6253/eTutorWcfService (using net.tcp in app).

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

Server app.config:

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

The client code:

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

When the client tries to connect, the output window of the server shows an SecurityTokenValidationException but I'm not sure what to do about that or if it means something relevant. I'm sure this has something to do with security but I don't know what to add where.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Velocedge
  • 1,222
  • 1
  • 11
  • 35
  • Local host may be configured different on two PCs. Check host files : C:\Windows\System32\Drivers\etc\hosts – jdweng Jan 01 '19 at 15:23
  • No entries in the hosts file on either computer. – Velocedge Jan 01 '19 at 15:38
  • Use sniffer like wireshark or fiddler and compare results on working PC and non working PC. Look at http response status to see if you are getting 200 done. Also check the TCP to see if you are getting [FIN] which terminates a TCP connection indicating finish. – jdweng Jan 01 '19 at 15:44
  • Maybe your entry ` ` in the client config has to do with the `SecruityTokenValidationException`. I don't know, why it is in the config. – H.G. Sandhagen Jan 01 '19 at 15:57
  • On the identity, it gets added automatically at some point with "msi/steve" (host name/user). I've taken out the value and the node but get the same error. – Velocedge Jan 01 '19 at 17:18
  • Have you tried running the server and/or client as Administrator? – rfmodulator Jan 01 '19 at 17:36
  • Both are running as administrator. Thinking there must be a way to set the credentials or something like that. – Velocedge Jan 01 '19 at 17:51
  • I think it's because you're binding only to the localhost interface, but your connecting via the IP. Try binding to the local IP in your app.config: `` – rfmodulator Jan 01 '19 at 17:58
  • The line: eTutorServiceReference.IeTutorMessageClient client = new eTutorServiceReference.IeTutorMessageClient("NetTcpBinding_IeTutorMessage", address); should override the app.config. But I tried it anyway and get the same message. – Velocedge Jan 01 '19 at 18:48
  • There are posts about setting the in the bindings but I can't figure out where to put them without it saying "invalid child node". – Velocedge Jan 01 '19 at 18:52
  • Sorry, I should have been more clear, change it in the server app.config. Your server is only listening to incoming connections on the loopback interface. That's why it only works when the client and server are both on the same machine. – rfmodulator Jan 01 '19 at 18:53
  • No, I understood you the first time. I changed the app.config... no difference. – Velocedge Jan 01 '19 at 19:00
  • You need that binding to listen remotely regardless... now you need to figure out your certificate issue. – rfmodulator Jan 01 '19 at 19:02
  • I have noticed that you have migrated the server address. Why did you not change the generated endpoint address in the client configuration file? I suggest that you add the service reference again in the client. The generated endpoint address is then modified. – Abraham Qian Jan 02 '19 at 07:09
  • Because the endpoint is changed with: EndpointAddress address = new EndpointAddress("net.tcp://" + eTutorServiceIp + ":6254/eTutorWcfService"). However, I did re-add the service referenced with the changed address but it's returning the error: TCP error code 10061: No connection could be made because the target machine actively refused it. – Velocedge Jan 02 '19 at 10:42

2 Answers2

1

First, Nettcpbinding use transport security mode and authenticate the client with windows credential by default.
WCF throws exception that the server has rejected the client credentials, what is the default security mode for NetTCP in WCF
Then, when we change the server configuration and re-host the service, we should re-generate the client proxy class when we calling it. besides, we may need to change the endpoint address in the client configuration since Localhost is generated by default.

I can live with this but would really like to know how to do it without security.

At last, when we change the security to None, the client does not need to provide the credentials to invoke the service. I suggest you re-host the service and re-generate the client proxy class. I have made a demo, wish it is useful to you.

Server end(console application)

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

App.config

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

Client end.

ServiceReference1.ServiceClient client = new ServiceReference1.ServiceClient();
            try
            {
                Console.WriteLine(client.SayHello());
            }
            catch (Exception)
            {

                throw;
            }

App.config

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

Feel free to let me know if there is anything I can help with.

Abraham Qian
  • 7,117
  • 1
  • 8
  • 22
0

I added the following code and it works:

client.ClientCredentials.Windows.ClientCredential.UserName = runAs;
client.ClientCredentials.Windows.ClientCredential.Password = runAsPassword;
client.ClientCredentials.Windows.ClientCredential.Domain = runAsDomain;

However, I'd like to do this without security since it will be placed on multiple servers, none of which will have a public IP. I've tried to add to the bindings but on the client it's not a valid node and on the server, it stops the service from starting. I tried to add the following code to the server but it won't open the ServiceHost:

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

I can live with this but would really like to know how to do it without security.

Velocedge
  • 1,222
  • 1
  • 11
  • 35