2010-03-30 345 views
19

一旦安全通道已經註冊,我無法使用不安全的通道。下面的代碼僅適用於客戶端,不安全的渠道之前註冊。混合安全和不安全通道

是否可以混合安全和不安全的渠道,沒有任何約束的註冊順序?

using System; 
using System.Collections; 
using System.Runtime.Remoting; 
using System.Runtime.Remoting.Channels; 
using System.Runtime.Remoting.Channels.Tcp; 

public class SampleObject : MarshalByRefObject 
{ 
    public DateTime GetTest() { return DateTime.Now; } 
} 
public class SampleObject2 : MarshalByRefObject 
{ 
    public DateTime GetTest2() { return DateTime.Now; } 
} 
static class ProgramClient 
{ 
    private static TcpClientChannel RegisterChannel(bool secure, string name, int priority) 
    { 
     IDictionary properties = new Hashtable(); 
     properties.Add("secure", secure); 
     properties.Add("name", name); 
     properties.Add("priority", priority); 
     var clientChannel = new TcpClientChannel(properties, null); 
     ChannelServices.RegisterChannel(clientChannel, false); 
     return clientChannel; 
    } 
    private static void Secure() 
    { 
     RegisterChannel(true, "clientSecure", 2); 
     var testSecure = (SampleObject2)Activator.GetObject(typeof(SampleObject2), "tcp://127.0.0.1:8081/Secured.rem"); 
     Console.WriteLine("secure: " + testSecure.GetTest2().ToLongTimeString()); 
    } 
    private static void Unsecure() 
    { 
     RegisterChannel(false, "clientUnsecure", 1); 
     var test = (SampleObject)Activator.GetObject(typeof(SampleObject), "tcp://127.0.0.1:8080/Unsecured.rem"); 
     Console.WriteLine("unsecure: " + test.GetTest().ToLongTimeString()); 
    } 
    internal static void MainClient() 
    { 
     Console.Write("Press Enter to start."); 
     Console.ReadLine(); 
     // Works only in this order 
     Unsecure(); 
     Secure(); 
     Console.WriteLine("Press ENTER to end"); 
     Console.ReadLine(); 
    } 
} 
static class ProgramServer 
{ 
    private static TcpServerChannel RegisterChannel(int port, bool secure, string name) 
    { 
     IDictionary properties = new Hashtable(); 
     properties.Add("port", port); 
     properties.Add("secure", secure); 
     properties.Add("name", name); 
     //properties.Add("impersonate", false); 
     var serverChannel = new TcpServerChannel(properties, null); 
     ChannelServices.RegisterChannel(serverChannel, secure); 
     return serverChannel; 
    } 
    private static void StartUnsecure() 
    { 
     RegisterChannel(8080, false, "unsecure"); 
     RemotingConfiguration.RegisterWellKnownServiceType(typeof(SampleObject), "Unsecured.rem", WellKnownObjectMode.Singleton); 
    } 
    private static void StartSecure() 
    { 
     RegisterChannel(8081, true, "secure"); 
     RemotingConfiguration.RegisterWellKnownServiceType(typeof(SampleObject2), "Secured.rem", WellKnownObjectMode.Singleton); 
    } 
    internal static void MainServer() 
    { 
     StartUnsecure(); 
     StartSecure(); 
     Console.WriteLine("Unsecure: 8080\n Secure: 8081"); 
     Console.WriteLine("Press the enter key to exit..."); 
     Console.ReadLine(); 
    } 
} 
class Program 
{ 
    static void Main(string[] args) 
    { 
     if (args.Length == 1 && args[0] == "server") 
      ProgramServer.MainServer(); 
     else 
      ProgramClient.MainClient(); 
    } 
} 

編輯:在.NET 4和VS無變化2010

+3

你說它「不起作用」;你能澄清它在做什麼嗎? – 2011-12-13 03:34:07

+0

@ M.Babcock你的評論是一個非常古老的問題,使用誰已經幾個月沒有。只是fyi – 2011-12-13 03:56:44

+0

我知道這是一個相當古老的問題,但認爲它仍然相關,因爲版主還沒有停用它。如果您覺得沒有必要,請隨時刪除我的回覆。 – 2011-12-13 04:58:10

回答

1

這是有趣的復古的問題,我花了大約一個星期試圖解決這個問題,必須實現一個變通。但是這裏是我發現的:答案很可能:不,你不能。

說明:.NET遠程處理不允許您在創建對象時選擇使用哪個客戶端通道。在服務器端,顯然它會使用監聽端口的通道,但在客戶端,它只會使用任何可用的,甚至創建一個新的 - 儘管我總是註冊自己的。

因此,看起來(我無法在文檔中的任何地方找到它),如果有一個安全的客戶端通道可用,那個被使用。因此,在問題的例子中,遠程對象是針對安全通道創建的,但它期望不安全的通道 - 因此它失敗。在首先創建一個不安全的連接的情況下 - 它的工作原理是因爲在創建遠程對象時沒有安全的客戶端通道,因此使用了不安全的客戶端通道。

替代方法:

  1. 創建一個單獨的應用程序域,例如,安全通道。
  2. 在該AppDomain中,創建一個將連接到安全的客戶端對象。
  3. 對所有不安全的通道使用默認的AppDomain。