2015-10-19 83 views
8

我們有一個服務器,我們用.Net遠程連接。.Net Remoting:指出使用哪個本地接口連接到一個服務器

服務器在兩個網絡上,客戶端在兩個網絡上。客戶端和服務器只有一個共同的網絡: enter image description here

使用發現,我們找到服務器的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嗎?

編輯

我發現了一些可能被interessting,我注意到,對於簡單的查詢和響應,在.NET遠程工作正常,但對於其中的一些,查詢給出了一個對象,這將是用作服務的回調,在這種情況下,它不起作用。

我剛剛得到.Net的源代碼來檢查這是如何完成的,但是我沒有發現它是爲相反方向創建的代理。

雖然擁有TcpChannel的源代碼,但我發現在某些時候,服務器端(它將建立與客戶端回調的連接)的方法接收到帶有正確遠程IP的請求但結尾的URI中有錯誤的IP: enter image description here

+0

您是否嘗試添加'bindTo'設置? https://msdn.microsoft.com/en-us/library/ms973907.aspx – rene

+0

@rene是的,但作爲spec狀態:「此屬性只能在服務器端使用。」 – J4N

+0

好吧,這可能有點破解,但如何在服務器上添加路由到路由表以便爲該IP使用特定的NIC?僅用於測試來驗證它只是一個路由問題。 – rene

回答

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連接[這可能accually如果網絡工作有一些意思是要達到10.11.xx而不通過10.10.xx]。

+0

我們的配置是不幸的是在代碼中(而不是XML),但我們試圖將'bindTo'和'machineName'設置爲期望的IP,但它仍然不起作用:(我更新了示例以顯示我們如何做到了這一點 – J4N

+0

我明白了。也許你可以嘗試改變Windows中的網卡順序,讓系統先嚐試使用正確的網絡?像這樣:https://www.google.se/search?q=nic+order+windows&rlz=1CDGOYI_enSE595SE595&hl=en-GB&prmd=ivn&source=lnms&tbm=isch&sa=X&ved=0ahUKEwj52LyF96jQAhUGFiwKHat-B​​hkQ_AUIBygB&biw=414&bih=660 –

+0

是的,我們只是試圖那昨天,它沒有幫助,我們一旦獲得成功,但是再次失敗(並且恢復這個返回具有相同的行爲)。 – J4N

0

我們最終得到了TcpChannel的代碼,基本上,我們存儲了存儲在頭文件中的源IP地址,然後我們替換了我們在IChannelDataStore中擁有的URI。我們還確保客戶端使用相同的端口監聽每個地址。一種黑客,但它讓我們擺脫困境...

+0

對於所有這些都是神聖的!! ......很高興你終於通過了它! :) –