【问题标题】:.Net Remoting: Indicate which local interface to use to connect to one server.Net Remoting:指示使用哪个本地接口连接到一台服务器
【发布时间】:2016-01-17 16:38:39
【问题描述】:

我们有一个与 .Net 远程连接的服务器。

服务器在两个网络上,客户端在两个网络上。客户端和服务器只有一个公共网络:

使用发现,我们找到服务器的 IP(在本例中为:10.10.10.110)。我们创建TcpChannel 并连接到服务器。

服务器接收到调用,但是当它尝试向客户端接收器发送一些信息时。我们得到一个异常,说我们试图将数据发送到一个无法访问的 IP(10.12.10.100)。

所以服务器正确地宣布了他的地址,但是我们如何指示客户端使用具有特定 IP 的网络接口?

一些代码:

客户端,初始化:

IDictionary tcpChannelConfiguration = new Hashtable();
string instanceName = "RemotingClient" + Utils.GenerateRandomString(5);
tcpChannelConfiguration["name"] = instanceName);
tcpChannelConfiguration["port"] = 0;
tcpChannelConfiguration["machineName"] = m_interfaceToHost;//This is containing the local interface to use
tcpChannelConfiguration["bindTo"] = m_interfaceToHost;
IClientChannelSinkProvider formatClient = new BinaryClientFormatterSinkProvider(tcpChannelConfiguration, null);
IClientChannelSinkProvider identityFormatClient = new IdentityClientSinkProvider{Next = formatClient};
BinaryServerFormatterSinkProvider formatServer = new BinaryServerFormatterSinkProvider(tcpChannelConfiguration, null)
{TypeFilterLevel = TypeFilterLevel.Full};
m_channel = new TcpChannel(tcpChannelConfiguration, identityFormatClient, formatServer);
ChannelServices.RegisterChannel(m_channel, false);

//Then we get the remote object:
IServer server  = (IServer)Activator.GetObject(typeof(IServer), String.Format("tcp://{0}:{1}/{2}", m_ipAddress, m_port, instanceName));
[...]

这是我在服务器端遇到的例外情况:

System.Net.Sockets.SocketException (0x80004005): A socket operation was attempted to an unreachable network 10.12.10.100:54330

Server stack trace: 
   at System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress)
   at System.Net.Sockets.Socket.Connect(EndPoint remoteEP)
   at System.Runtime.Remoting.Channels.RemoteConnection.CreateNewSocket(EndPoint ipEndPoint)
   at System.Runtime.Remoting.Channels.RemoteConnection.CreateNewSocket()
   at System.Runtime.Remoting.Channels.RemoteConnection.GetSocket()
   at System.Runtime.Remoting.Channels.SocketCache.GetSocket(String machinePortAndSid, Boolean openNew)
   at System.Runtime.Remoting.Channels.Tcp.TcpClientTransportSink.SendRequestWithRetry(IMessage msg, ITransportHeaders requestHeaders, Stream requestStream)
   at System.Runtime.Remoting.Channels.Tcp.TcpClientTransportSink.ProcessMessage(IMessage msg, ITransportHeaders requestHeaders, Stream requestStream, ITransportHeaders& responseHeaders, Stream& responseStream)
   at System.Runtime.Remoting.Channels.BinaryClientFormatterSink.SyncProcessMessage(IMessage msg)

如何向客户端指示它必须向服务器提供哪个 IP/接口?

我们可以通过自定义ClientSinkProvider 来做到这一点吗?

编辑

我发现了一些有趣的东西,我注意到对于简单的查询响应,.Net Remoting 工作正常,但是对于其中一些,查询提供了一个对象,该对象将被服务用作回调,并且在这种情况下,它不起作用。

我刚刚获得了 .Net 的源代码来检查这是如何完成的,但我还没有发现相反方向的代理的创建。

虽然拥有 TcpChannel 的源代码,但我看到,在某些时候,服务器端的方法(它将与客户端上的回调建立连接)接收到标头中具有正确远程 IP 的请求,但以 URI 中的错误 IP 结束:

【问题讨论】:

  • 您是否尝试添加bindTo 设置? msdn.microsoft.com/en-us/library/ms973907.aspx
  • @rene 是的,但正如规范状态:“这个属性只能在服务器端使用。”
  • 好的,这可能是一个小技巧,但是如何在服务器上的路由表中添加一个路由以使用该 IP 的特定 NIC?只是为了测试以验证它只是一个路由问题。
  • @rene : 我不是networkink的专业人士,但是你会怎么做呢?是否可以通过我们的 .Net 应用程序完成?我们必须为每个客户都这样做吗?(因为我们不了解所有客户)
  • 实际上,由于问题发生在服务器向客户端发送响应时,您可以在问题中包含一些服务器端代码。

标签: c# .net communication .net-remoting


【解决方案1】:

几年前我写了几个远程应用程序,尽管我没有得到这个确切的错误,但我的理解是服务器试图通过连接回客户端来返回结果,但随后使用了错误的 IP。

如果您明确指定客户端用于与服务器通信的 IP,会发生什么情况?尝试将以下内容添加到您的客户端 .config 文件中:

<configuration>
    <system.runtime.remoting>
        <application>
            <channels>
                <channel ref="tcp" port="0" bindTo="10.10.10.100" />
            </channels>
        </application>
    </system.runtime.remoting>
</configuration>

这应该确保连接和流量通过请求的 IP 路由 - 而不是使用 10.12.10.100 进行连接[如果该网络有某种方法可以在不通过 10.10.x.x 的情况下到达 10.11.x.x,这可能会起作用]。

【讨论】:

  • 不幸的是,我们的配置是在代码中(不是 XML),但是我们尝试将 bindTomachineName 设置为预期的 IP,它仍然不起作用:( 我更新了示例展示我们是如何做到的
  • 我明白了。或许您可以尝试更改 Windows 中的 NIC 顺序,以使系统首先尝试使用正确的网络?像这样:google.se/…
  • 是的,我们昨天刚刚尝试过,它没有帮助,我们成功了一次,但随后又失败了(并且恢复此行为具有相同的行为)。
  • 嗯。那么接下来要尝试的可能是提高频道优先级? tcpChannelConfiguration["优先级"] = 99;
  • 我会检查的(但我只有一个频道,所以不确定它有影响)
【解决方案2】:

我们最后得到了TcpChannel 的代码,基本上,我们存储了存储在标头中的源IpAddress,然后我们替换了IChannelDataStore 中的URI。我们还确保客户端侦听具有相同端口的每个地址。有点像黑客,但它让我们摆脱了麻烦......

【讨论】:

    【解决方案3】:

    重新排序网络连接优先级对我来说很有帮助。

    http://ecross.mvps.org/howto/change-network-connection-priority-in-windows-10.htm

    1. 按 Windows 键 + X 并从菜单中选择网络连接。
    2. 按 ALT 键,单击高级,然后单击高级设置。
    3. 选择网络连接并单击箭头以优先考虑网络连接。

    1. 组织完网络连接的优先级后单击确定。当连接可用时,计算机现在将按照顺序执行。

    【讨论】:

      猜你喜欢
      • 2013-02-06
      • 1970-01-01
      • 2023-03-23
      • 2012-10-29
      • 2018-01-26
      • 1970-01-01
      • 2017-04-20
      • 1970-01-01
      相关资源
      最近更新 更多