Specify the outgoing IP address to use with WCF client

前端 未结 3 1828
忘了有多久
忘了有多久 2020-12-06 15:35

How to define the LocalEndPoint to use by a WCF client when calling a WCF service (if the client machine has multiple IP addresses) ?

I have a machine located

相关标签:
3条回答
  • 2020-12-06 15:56

    This is an older thread, but I have a suggestion for anyone finding this one as it lead me to track down a slightly different solution. We have two processes that we needed to run on separate processes on the same server.

    The issue was each by default chose the primary address that was bound to the NIC. We couldn't find a way to get the app to bind to a secondary address on the NIC.

    The workaround was to add a second NIC to the VM, move the secondary IP to the second NIC as the primary IP of the 2nd NIC. In Windows, you cannot have two default gateways (even if they point to the same address).

    So, on the 2nd NIC, we assigned the IP and the Subnet Mask only. To get the traffic to route out the proper interface, we added a route statement in the format of:

    route add 4.3.2.1 mask 255.255.255.255 1.2.3.4 IF 0x10002
    

    Where the host we needed the process to talk to is 4.3.2.1, the local Default Gateway is 1.2.3.4 and the second NIC shows up in the routing table as interface number 0x10002 (from route print).

    I hope this helps. I have a few more grey hairs because of this one.

    0 讨论(0)
  • 2020-12-06 15:58

    Had a hard time finding the answer to this one myself, so i'll share my solution in case someone else comes by here.

    Below is a method that returns a wcf soapservice. The code will try to use a specific ip if available. I did this check to have it working on a test machine as well.

        public static proposalSoapClient getService()
        {
            string serviceurl = "http://somesite.dk/proposal.asmx";
            var localIpAddress = IPAddress.Parse("123.123.123.123");
            var hasLocalAddress = Dns.GetHostEntry(Dns.GetHostName()).AddressList.Any(ip => ip.AddressFamily == AddressFamily.InterNetwork && ip.Equals(localIpAddress));
    
            var binding = new System.ServiceModel.BasicHttpBinding("proposalSoap"); //name of binding in web.config
            var endpoint = new EndpointAddress(serviceurl);
            ServicePoint servicePoint = ServicePointManager.FindServicePoint(new Uri(serviceurl));
            servicePoint.BindIPEndPointDelegate = (sp, rm, retryCount) => { return new IPEndPoint(hasLocalAddress ? localIpAddress : IPAddress.Any, 0); };
            return new proposalSoapClient(binding, endpoint);
        }
    

    Also when i am on the test server i had to use a proxy to get to the service. (i used fiddler as proxy on the machine that had access to the service). Below is the same code but with added section for proxy when on the test server.

        public static proposalSoapClient getService()
        {
            string serviceurl = "http://somesite.dk/proposal.asmx";
            var localIpAddress = IPAddress.Parse("123.123.123.123");
            var hasLocalAddress = Dns.GetHostEntry(Dns.GetHostName()).AddressList.Any(ip => ip.AddressFamily == AddressFamily.InterNetwork && ip.Equals(localIpAddress));
    
            var binding = new System.ServiceModel.BasicHttpBinding("proposalSoap"); //name of binding in web.config
            var endpoint = new EndpointAddress(serviceurl);
            ServicePoint servicePoint = ServicePointManager.FindServicePoint(new Uri(serviceurl));
    
        #if DEBUG
            Uri proxyUri = new Uri("http://someothersite.dk:8888");
            binding.ProxyAddress = proxyUri;
            binding.BypassProxyOnLocal = false;
            binding.UseDefaultWebProxy = false;
            servicePoint = ServicePointManager.FindServicePoint(serviceurl, new WebProxy(proxyUri, false));
        #endif
    
            servicePoint.BindIPEndPointDelegate = (sp, rm, retryCount) => { return new IPEndPoint(hasLocalAddress ? localIpAddress : IPAddress.Any, 0); };
            return new proposalSoapClient(binding, endpoint);
        }
    
    0 讨论(0)
  • 2020-12-06 15:59

    Sounds like the routing tables are a little messed up on the server for what you want to do. Instead of trying to correct for it in the app, tweak the interface metrics and or routing tables on the machine to prefer the internal interface for traffic destined for that network. Here is an old reference, but should be more or less valid.

    I don't think .NET sockets will allow you to explicitly choose a source interface- closest thing would be the DontRoute SocketOption, but even there, you'd probably have to roll a custom binding and transport to have that option available.

    0 讨论(0)
提交回复
热议问题