我们有一台服务器,我们用.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的源代码来检查这是如何完成的,但是我没有找到YET为相反方向创建代理。
在拥有TcpChannel的源代码时,我看到在某些时候,服务器端的方法(将与客户端上的回调建立连接)在头中接收到具有正确远程IP的请求,但在URI中使用错误的IP结束:
答案 0 :(得分: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.11.x.x但没有通过10.10.x.x,这可能会有效。
答案 1 :(得分:0)
我们最后得到了TcpChannel
的代码,基本上,我们存储了存储在标头中的源IpAddress,然后我们替换了IChannelDataStore
中的URI。此外,我们确保客户端使用相同的端口侦听每个地址。有点像黑客,但它让我们摆脱了麻烦...
答案 2 :(得分:-1)
重新排序网络连接优先级对我的情况有帮助。
http://ecross.mvps.org/howto/change-network-connection-priority-in-windows-10.htm