2010-03-30 8 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(); 
    } 
} 

संपादित करें: नेट 4 और वी.एस. के साथ कोई परिवर्तन 2010

+3

आप कहते हैं कि यह "काम नहीं करता"; क्या आप यह स्पष्ट कर सकते हैं कि यह क्या कर रहा है? –

+0

@ एम। बाबकॉक आपकी टिप्पणी एए बहुत पुराने प्रश्न पर है, जिसका उपयोग कुछ महीनों तक नहीं किया गया है। बस fyi –

+0

मुझे पता था कि यह एक काफी पुराना सवाल था, लेकिन लगा कि यह अभी भी प्रासंगिक है क्योंकि मॉडरेटर ने इसे अभी तक निष्क्रिय नहीं किया है। अगर आपको लगता है कि यह अनावश्यक है तो मेरी प्रतिक्रिया को हटाने के लिए स्वतंत्र महसूस करें। –

उत्तर

1

यह दिलचस्प पुराने सवाल है, मैं एक सप्ताह के बारे में खर्च कर दिया है है इस समस्या को हल करने की कोशिश कर, और एक काम के आसपास लागू करने के लिए किया था। लेकिन यहां मैंने जो खोजा है: उत्तर सबसे अधिक संभावना है: नहीं, आप नहीं कर सकते।

स्पष्टीकरण: .NET रीमोटिंग आपको ऑब्जेक्ट बनाने के दौरान किस क्लाइंट चैनल का उपयोग करने का विकल्प नहीं चुनने देता है। सर्वर की ओर, यह चैनल को पोर्ट में सुनकर चैनल का उपयोग करेगा, जाहिर है, लेकिन क्लाइंट साइड पर यह किसी भी उपलब्ध या यहां तक ​​कि एक नया निर्माण भी करेगा - हालांकि मैं हमेशा अपना खुद का पंजीकरण करता हूं।

तो ऐसा लगता है (मुझे इसे दस्तावेज़ में कहीं भी नहीं मिला) कि यदि कोई सुरक्षित ग्राहक चैनल उपलब्ध है, तो वह उपयोग किया जाता है। तो उदाहरण में, सुरक्षित चैनल के खिलाफ रिमोट ऑब्जेक्ट बनाया गया है, लेकिन यह असुरक्षित की अपेक्षा करता है - इस प्रकार यह विफल हो जाता है। पहले असुरक्षित कनेक्शन बनाने के मामले में - यह काम करता है क्योंकि उस समय रिमोट ऑब्जेक्ट बनाया गया है, वहां कोई सुरक्षित क्लाइंट चैनल नहीं है, इसलिए असुरक्षित क्लाइंट चैनल का उपयोग किया जाता है।

वैकल्पिक हल:

  1. सुरक्षित चैनल के लिए एक अलग AppDomain, उदाहरण के लिए, बनाएँ।
  2. उस ऐपडोमेन में, क्लाइंट ऑब्जेक्ट बनाएं जो सुरक्षित से कनेक्ट होगा।
  3. सभी असुरक्षित चैनलों के लिए अपने डिफ़ॉल्ट ऐपडोमेन का उपयोग करें।
संबंधित मुद्दे