2010-08-25 15 views
7

मेरे पास net.tcp WCF सेवा है, और मैं ओएस को पोर्ट को चुनना चाहता हूं जिसे इसे सुनना चाहिए। इसलिए मैंने पोर्ट को अपने यूआरआई में 0 पर सेट किया है, और netstat पुष्टि करता है कि ओएस ने 5000 रेंज में एक पोर्ट चुना है।मैं उस बंदरगाह को कैसे प्राप्त कर सकता हूं जिस पर डब्ल्यूसीएफ सेवा सुन रही है?

सेवा प्रक्रिया के अंदर कोड में उठाए गए वास्तविक पोर्ट को मैं कैसे पा सकता हूं?

कुछ कोड को दिखाने के लिए मैं क्या कोशिश की है:

Type serviceType = ...; 
Uri address = new Uri("net.tcp://0.0.0.0:0/Service/"); 
ServiceHost serviceHost = new ServiceHost(serviceType, address); 
ServiceEndpoint endPoint = serviceHost.AddServiceEndpoint(type, binding, ""); 
int port1 = endPoint.ListenUri.Port; // returns 0 
int port2 = serviceHost.BaseAddresses.First().Port; // also returns 0 
+0

यादृच्छिक बंदरगाह पर सुनने के लिए सेवा प्राप्त करना काफी असामान्य है - क्या ऐसा कोई कारण है जिसे आप करना चाहते हैं? – Cocowalla

+0

@ कोकोवाल्ला: सेवा एक कार्यकर्ता प्रक्रिया का हिस्सा है, इसलिए समय पर एक से अधिक हो सकते हैं, और हम उन समाधानों को देख रहे हैं जिनमें .NET TCP पोर्ट शेयरिंग शामिल नहीं है। – ngoozeff

+0

संभावित डुप्लिकेट [मैं डब्ल्यूसीएफ सेवा का सुनवाई पता/बंदरगाह कैसे प्राप्त कर सकता हूं?] (Http://stackoverflow.com/questions/2207348/how-can-i-get-the-listening-address-port-of -ए-डब्ल्यूसीएफ-सेवा) – mafu

उत्तर

10

सुनिश्चित नहीं हैं कि अगर इस में मदद मिलेगी, लेकिन वहाँ एक ऐसी ही सवाल पहले से ही पर तो चलो: How can I get the listening address/port of a WCF service?

एक प्रस्तुत जवाब के प्रासंगिक बात यह है कि आप कोशिश कर सकते हैं:

foreach (var channelDispatcher in serviceHost.ChannelDispatchers) 
{ 
      Console.WriteLine(channelDispatcher.Listener.Uri); 
} 

तो शायद आपको channelDispatcher.Listener.Uri.Port की आवश्यकता हो।

आशा है कि इससे मदद मिलती है!

+1

@ डी होर्स्टर: दुर्भाग्यवश वह यूआरआई वापस देता है जिसे मैंने पास किया था। दूसरे प्रश्न के लिए सूचक के लिए धन्यवाद। – ngoozeff

+3

@ डी होरस्टर: ऐसा लगता है कि हमारे पास विजेता है। मुझे एंडपॉइंट भी सेट करना पड़ा। लिस्टेनउरीमोड = सुनोउरीमोड.इनिक; इसके लिए काम करने के लिए (और बाध्यकारी पर बंदरगाह साझाकरण अक्षम)। – ngoozeff

+0

क्या आपने अपना कॉल खोलने के लिए किया था? – BozoJoe

1

एक विकल्प के रूप में, आप अपने आप को WCF का उपयोग करने के लिए एक मुक्त बंदरगाह मिल सकता है: here से

private int FindPort() 
{ 
    IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, 0); 

    using (Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) 
    { 
     socket.Bind(endPoint); 
     IPEndPoint local = (IPEndPoint)socket.LocalEndPoint; 
     return local.Port; 
    } 
} 

कोड।

+1

यह सुरक्षित नहीं है। सॉकेट का निपटारा करने के बाद कोई और बंदरगाह छीन सकता है लेकिन सर्विसहोस्ट खोला जाने से पहले। तो यह विधि sporadically विफल हो सकता है। मुझे सही रास्ते पर लाने के लिए – BatteryBackupUnit

3

एक बार सेवा शुरू हो जाने के बाद आप अंतराल के पूर्ण विवरण प्राप्त कर सकते हैं जो वास्तव में विवरण से बनाए गए थे। एंडपॉइंट्स संग्रह (यह ओपन() के बाद तक काम नहीं करता है)। इस संग्रह से आप पता प्राप्त कर सकते हैं। असुविधाजनक रूप से आपको बंदरगाह के पते को पार्स करना होगा।

यह है कि मेरा सर्वर प्रत्येक सेवा के बाद लॉग ऑन करता है()।

 serviceHost.Open(); 

     // Iterate through the endpoints contained in the ServiceDescription 
     System.Text.StringBuilder sb = new System.Text.StringBuilder(string.Format("Active Service Endpoints:{0}", Environment.NewLine), 128); 
     foreach (ServiceEndpoint se in serviceHost.Description.Endpoints) 
     { 
      sb.Append(String.Format("Endpoint:{0}", Environment.NewLine)); 
      sb.Append(String.Format("\tAddress: {0}{1}", se.Address, Environment.NewLine)); 
      sb.Append(String.Format("\tBinding: {0}{1}", se.Binding, Environment.NewLine)); 
      sb.Append(String.Format("\tContract: {0}{1}", se.Contract.Name, Environment.NewLine)); 
      foreach (IEndpointBehavior behavior in se.Behaviors) 
      { 
       sb.Append(String.Format("Behavior: {0}{1}", behavior, Environment.NewLine)); 
      } 
     } 

     Console.WriteLine(sb.ToString()); 
+0

+1 – ngoozeff

संबंधित मुद्दे

 संबंधित मुद्दे