【发布时间】: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