2008-10-14 15 views
9

मैं एक बार कॉलबैक को संभालने के लिए एक बार HTTP सर्वर का उपयोग करने की कोशिश कर रहा हूं और रुबी में एक मुफ्त टीसीपी पोर्ट खोजने में मदद की ज़रूरत है।रूबी का उपयोग करके आपको एक मुफ्त टीसीपी सर्वर पोर्ट कैसे मिलता है?

require 'socket' 
t = STDIN.read 
port = 8081 
while s = TCPServer.new('127.0.0.1', port).accept 
    puts s.gets 
    s.print "HTTP/1.1 200/OK\rContent-type: text/plain\r\n\r\n" + t 
    s.close 
    exit 
end 

(यह मानक इनपुट पहले कनेक्शन के लिए गूँज और फिर मर जाता है।) मैं स्वचालित रूप से सुनने के लिए एक मुक्त बंदरगाह पा सकते हैं:

यह है कि मैं क्या कर रहा हूँ का कंकाल है पर?

यह एक दूरस्थ सर्वर पर नौकरी शुरू करने का एकमात्र तरीका प्रतीत होता है जो फिर एक अद्वितीय नौकरी आईडी के साथ वापस कॉल करता है। इस नौकरी आईडी को फिर स्थिति की जानकारी के लिए पूछताछ की जा सकती है। जब नौकरी शेड्यूल करते समय मूल डिजाइनर सिर्फ नौकरी आईडी वापस नहीं कर पाएंगे तो मुझे कभी पता नहीं चलेगा। एक एकल बंदरगाह का उपयोग नहीं किया जा सकता है क्योंकि एकाधिक कॉलबैक के साथ संघर्ष हो सकता है; इस तरह बंदरगाहों का उपयोग केवल + - 5 सेकंड के लिए किया जाता है।

उत्तर

-7

मुझे लगता है कि आप अनुक्रम में सभी बंदरगाहों> 5000 (उदाहरण के लिए) को आजमा सकते हैं। लेकिन आप क्लाइंट प्रोग्राम से संवाद कैसे करेंगे कि आप किस पोर्ट को सुन रहे हैं? पोर्ट पर निर्णय लेने के लिए यह आसान लगता है, और फिर इसे आसानी से कॉन्फ़िगर करने योग्य बनाते हैं, अगर आपको अपनी स्क्रिप्ट को विभिन्न परिवेशों के बीच स्थानांतरित करने की आवश्यकता है।

HTTP के लिए, मानक पोर्ट 80 वैकल्पिक बंदरगाहों मैंने देखा का उपयोग किया है 8080, 880 और 8000

+0

प्रश्न (अंतिम) प्रश्न के अंतिम अनुच्छेद देखें। –

+1

यह स्वीकार्य उत्तर नहीं होना चाहिए; नीचे http://stackoverflow.com/a/201528/3528 देखें। –

-6

यादृच्छिक बंदरगाहों पर संवाद नहीं है कर रहे हैं। एक डिफ़ॉल्ट एक चुनें और इसे विन्यास योग्य बनाओ। यादृच्छिक बंदरगाह फायरवॉल के साथ असंगत हैं। एफ़टीपी ऐसा करता है और इसके लिए फ़ायरवॉल समर्थन एक दुःस्वप्न है - इसे पैकेट का गहराई से निरीक्षण करना है।

+3

सवाल यह था कि उपयोग करने के लिए एक मुफ्त बंदरगाह कैसे ढूंढें, न कि यादृच्छिक बंदरगाह का उपयोग करना एक अच्छा विचार है या नहीं। – ZombieDev

+0

फ़ायरवॉल के माध्यम से सभी टीसीपी/आईपी यातायात बहता नहीं है। –

3

यह वास्तव में काफी आसान है जब आप एक पंक्ति में सब कुछ करने की कोशिश नहीं करते है: -/

require 'socket' 
t = STDIN.read 

port = 8080 # preferred port 
begin 
    server = TCPServer.new('127.0.0.1', port)  
rescue Errno::EADDRINUSE 
    port = rand(65000 - 1024) + 1024 
    retry 
end 

# Start remote process with the value of port 

socket = server.accept 
puts socket.gets 
socket.print "HTTP/1.1 200/OK\rContent-type: text/plain\r\n\r\n" + t 
socket.close 

यह सिद्ध (मजबूत शब्द) प्रश्न में टुकड़ा के रूप में ही।

+4

बस नाइट-पिक करने के लिए ... इस तरह यादृच्छिक रूप से चुनना एक असंबद्ध लूप है, और सैद्धांतिक रूप से सर्वर पर एक अनिर्धारित समय के लिए चला सकता है; एक ऐसी स्थिति जो पहले से ही उपयोग में अधिक बंदरगाहों को और भी बदतर हो जाती है। –

64

पोर्ट नंबर के लिए 0 पास करें। यह प्रणाली को आपके लिए अस्थायी बंदरगाह सीमा से बाहर एक बंदरगाह चुनने का कारण बन जाएगा। एक बार सर्वर बनाने के बाद, आप इसे अपने एडीआर के लिए पूछ सकते हैं, जिसमें उस पोर्ट को शामिल किया जाएगा जो सर्वर से जुड़ा हुआ है।

server = TCPServer.new('127.0.0.1', 0) 
port = server.addr[1] 
+0

मैं एक मूल सॉकेट (टीसीपीएसकेट नहीं) का उपयोग कर रहा हूं, जिसमें 'addr' विधि नहीं है। क्या आपको पता चलेगा कि मैं इस मामले में बंदरगाह कैसे प्राप्त कर सकता हूं? – troelskn

+3

अपने स्वयं के प्रश्न का उत्तर दें, 'socket.getsockname.unpack ("snA *") का उपयोग करें [1] ' – troelskn

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