强制WCF通道到IP地址

时间:2014-10-20 07:42:49

标签: c# wcf binding channel

我有两台计算机,它们通过以太网连接,我已经建立了一个WCF连接,这一切都正常,但是当我在本地PC上托管与我想要通信的那个相同的wcf然后做一个wcf请求通过一个频道,请求不会到远程电脑,而是到我的本地电脑。有没有办法强制来自频道的wcf请求通过特定的ipaddress而不只是去任何一个?

我将尝试解释我是如何使用它的:

有两台计算机它们都很相似,并且有两台网络适配器,它们具有相同的ipaddess并运行相同的wcf软件。所以例如适配器1的ipaddress是:10.10.10.1而另一个适配器是10.10.10.2在同一台PC上,而另一台pc是类似的。现在这两个PC需要通信,所以我连接两个网络适配器交叉示例:PC 1网络适配器一个转到PC 2网络适配器2.这样它们以2种方式连接。因此,如果我想与一个简单的套接字从一个到另一个进行通信并通过第二个适配器返回这一切都可以,因为我可以将套接字绑定到ipaddress,它将通过它绑定的适配器发送它。但这似乎不适用于WCF。如果我在一台电脑上有两个主机,一个用于适配器10.10.10.1,另一个用于10.10.10.2用于另一个适配器,我向远程电脑上的10.10.10.2发送消息,它将通过第二个网络adapeter进入

PC1 network adapter 1 (10.10.10.1) <--direct patch cable connection--> PC2 network adapter 2 (10.10.10.2)

PC1 network adapter 2 (10.10.10.2) <--direct patch cable connection--> PC2 network adapter 1 (10.10.10.1)

这些连接箭头是直接连接跳线!

所有网络适配器都托管了一个wcf,两台电脑上的软件都是相同的。

这一切都是为了实现冗余,多了两个pc可以用链接连接。

这是我如何设置远程主机请求的一个小例子:

public void Test()
        {
            string endPoint = "net.tcp://10.10.10.2:9985/connection";

            NetTcpBinding binding = new NetTcpBinding(SecurityMode.None);
            binding.ListenBacklog = 2000;
            binding.MaxConnections = 2000;
            binding.TransferMode = TransferMode.Buffered;
            binding.MaxReceivedMessageSize = 104857600;
            binding.SendTimeout = new TimeSpan(0, 1, 0);
            binding.CloseTimeout = new TimeSpan(0, 0, 1);
            binding.OpenTimeout = new TimeSpan(0, 0, 1);
            binding.ReceiveTimeout = new TimeSpan(0, 1, 0);
            //binding.HostNameComparisonMode = HostNameComparisonMode.Exact;
            //binding.PortSharingEnabled = false;

            ChannelFactory<Connection> pipeFactory = new ChannelFactory<Connection>(binding, new EndpointAddress(endPoint));

            var pipeProxy = this.ChannelFactory.CreateChannel();
            //fictional method: pipeProxy.SendRequestTunnelTo("10.10.10.1"); //this is the ipaddress that it should go out to however it goes out to "10.10.10.2" 
            //and this is another network adapter also on the local mashine and here is also a wcf host on

            ((IClientChannel)pipeProxy).AllowOutputBatching = true;
            ((IClientChannel)pipeProxy).Open();

            pipeProxy.SystemRequest(); //do function
        }

2 个答案:

答案 0 :(得分:0)

您的端点地址需要标识您要定位的IP地址。

答案 1 :(得分:0)

好的,这里的问题是路由。如果Windows认为它可以将流量直接传递到其他IP地址,它就会这样做。

在这种情况下,它无法区分它所知道的本地10.10.10.2和隐藏在NAT后面的另一个网络上的本地10.10.10.2。

首选解决方案是不使用相同的子网(因此有10.10.10.2和10.11.10.2或类似的子网),但有时需要进行重大更改。

下一个最佳选择是使用NAT的IP地址并将其端口转发。

假设你有这样的设置(带有2个ip地址的盒子是带有公共和内部IP的NATing路由器)......

10.10.10.2 --- [10.10.10.1 | 1.2.3.4] --- Internet --- [5.6.7.8 | 10.10.10.1] -- 10.10.10.2

然后左边的机器应该尝试连接到5.6.7.8,它应该将连接转发到右边的机器上(反之亦然,右边的机器连接到1.2.3.4)。

如果您的WAN设置使得计算机看起来位于同一网络中,那么问题就像在同一网络上一样。网络中的所有路由器都无法确定您的10.10.10.2,

如果您没有使用完全相同的IP地址,则可以使用Windows框中的路由表强制解决问题。这可以允许您指定优先路由,以便给定IP地址的所有流量都通过指定的NIC传出。不幸的是,除此之外,它不受你的控制,完全取决于网络硬件如何路由数据包。如果您能够在中间硬件上配置路由,则可以将路由整个路由到目的地,但这通常是一项非常多的工作,并且当工具包更新/替换时可能会被破坏。非标准。

如果您决定查看强制路线,请从Windows route command

开始

编辑:Re:强制通过接口进行路由...

语法为route add target mask gateway costmetric interfaceid

在命令提示符下运行route print并记下要在输出顶部使用的接口ID

然后添加这样的路线:

route add 10.10.10.2 255.255.255.255 10.10.10.2 1 [interface id from above]

在我的机器上

route add 10.10.10.2 255.255.255.255 10.10.10.2 1 11

请注意,在这种情况下,我们告诉它使用10.0.0.2作为网关。我不知道这样做的后果是什么,因为试图通过本地绑定端口访问自己的软件可能会非常混乱。最后一点需要注意的是:我没有一副物理机可供使用,我可以对此进行测试,并且虚拟机并不算实时,因为它们的网络略有不同。

我们提供的成本指标为1.这应该给它一个非常高的优先级,这意味着应该选择高于该IP地址的所有其他路由。

系统重新启动时路径将丢失。您可以在-p之后使用route add标志来使路由持久化。我建议您不要这样做,直到您确定它按预期工作。

第二次编辑:我认为你正在这里找到一个兔子洞。虽然有可能欺骗系统以这种方式工作,但它绝对不是一种常见用法,而且我还没能找到任何支持它的东西。

似乎您的根本问题是,在没有网络连接的情况下,在分配IP地址之前,您无法协商。

一些想法......

共享IP不会很强大,因此要与它分离。不是在URL中使用固定IP,而是以编程方式确定其他IP地址。

你可以有两个构建,一个使用.1 / .2,另一个使用.3 / .4。然后,任何build1都可以与任何build2通信,但不能与1-1或2-2通信。这有点尴尬,但您可以轻松工作。

最好是为您构建的每台计算机分配唯一的IP,然后提供检测其他计算机地址的方法。 Service location protocol可能是此方法的候选人。一旦知道了需要与之通信的IP地址,配置WCF应该是微不足道的。

如果分配唯一的IP是有问题的,您可能在所有节点上都有DHCP服务器,但只有在该网络(对)上不存在另一个节点时才打开它们。这样,每台机器最终都会得到有效的IP地址而无需事先配置。