लोकलहोस्ट पर, मैं एक मुफ्त पोर्ट नंबर कैसे चुन सकता हूं?


161

मैं अंतर-प्रक्रिया संचार के साथ खेलने की कोशिश कर रहा हूं और जब से मैं यह पता नहीं लगा सका कि विंडोज के तहत नामित पाइप का उपयोग कैसे किया जाए तो मुझे लगा कि मैं नेटवर्क सॉकेट का उपयोग करूंगा। सब कुछ स्थानीय स्तर पर होता है। सर्वर एक अलग प्रक्रिया में दासों को लॉन्च करने में सक्षम है और कुछ बंदरगाह पर सुनता है। दास अपना काम करते हैं और मास्टर को परिणाम प्रस्तुत करते हैं। मैं कैसे पता लगाऊं कि कौन सा पोर्ट उपलब्ध है? मुझे लगता है कि मैं पोर्ट 80 या 21 पर नहीं सुन सकता हूँ?

मैं पायथन का उपयोग कर रहा हूं, यदि वह विकल्प नीचे काटता है।

धन्यवाद!


1
संयोग से, यदि आप सिर्फ एक यादृच्छिक या यादृच्छिक-ईश पोर्ट संख्या (अधिमानतः 1024 से अधिक) चुनते हैं, तो यह संभवतः उपलब्ध होगा। आप पोर्ट 80 या 21 या जो भी उपयोग कर सकते हैं, जब तक कि कोई अन्य प्रोग्राम उस पर नहीं सुन रहा है। किसी भी समय, एक सामान्य प्रणाली पर, बंदरगाहों का केवल एक छोटा सा अंश उपयोग में होता है।
डेविड जेड

19
एक यादृच्छिक पोर्ट चुनना एक अच्छा विचार नहीं है - ओएस को आपके लिए एक लेने दें।
Corehpf

जवाबों:


225

किसी विशिष्ट पोर्ट से न बांधें, या पोर्ट 0 से बाँधें, जैसे sock.bind(('', 0))। OS फिर आपके लिए एक उपलब्ध पोर्ट चुनेगा। आप उस पोर्ट को प्राप्त कर सकते हैं जिसे उपयोग करके चुना गया था sock.getsockname()[1], और इसे दासों को पास करें ताकि वे वापस कनेक्ट कर सकें।


4
इसके उदाहरण के लिए stackoverflow.com/a/2838309/3538289 देखेंsock.bind(('',0))
cevaris

10
आप गुलामों की संख्या पर कैसे गुजरते हैं? मेरे लिए एक चिकन और अंडे की समस्या की तरह लगता है।
सेबस्टियन

2
यदि दासों को बंधन के बाद बनाया जाता है, तो आप उन्हें बनाते समय पैरामीटर के रूप में पास कर सकते हैं। वैकल्पिक रूप से आप इसे कुछ साझा मेमोरी या एक फाइल में लिख सकते हैं जिसे दोनों एक्सेस कर सकते हैं, या कुछ प्रसिद्ध पोर्ट नंबर के माध्यम से एक्सेस किया जाने वाला केंद्रीय सर्वर इसका ट्रैक रख सकता है।
mark4o

49

ऊपर लोगों ने जो समझाया है उसके स्निपेट के लिए:

import socket
from contextlib import closing

def find_free_port():
    with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as s:
        s.bind(('', 0))
        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        return s.getsockname()[1]

3
अगर लोकलहोस्ट पर: हो सकता है s.bind(('localhost', 0))कि बेहतर हो
codekyblue

3
निम्नलिखित जोड़ने के लिए भी अच्छा है ताकि आप अपने रिटर्न स्टेटमेंट से पहले जल्दी से उस पोर्ट का फिर से उपयोग कर सकें:s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
jonEbird

1
@ जोंएबर्ड socket.SO_REUSEADDRवास्तव में इस मामले में मदद करता है ? मैंने जो पढ़ा है, वह केवल इस बात से प्रासंगिक है कि जिस सॉकेट को बांधने की कोशिश की जा रही है, SO_REUSEADDRवह अप्रासंगिक है और क्या वह झंडा लिंचिंग सॉकेट पर सेट है।
कार्ल बार्टेल

41

सॉकेट को पोर्ट 0 से बाँधें। 1024 से 65535 तक के बेतरतीब फ्री पोर्ट को चुना जाएगा। आप चयनित पोर्ट को getsockname()सही के बाद पुनः प्राप्त कर सकते हैं bind()


2

आप जो चाहें पोर्ट पर सुन सकते हैं; आमतौर पर, उपयोगकर्ता अनुप्रयोगों को 1024 और उससे अधिक (65535 के माध्यम से) पोर्ट को सुनना चाहिए। यदि आपके पास श्रोताओं की एक चर संख्या है, तो मुख्य बात यह है कि अपने ऐप में एक रेंज आवंटित करें - 20000-21000, और CATCH EXCEPTIONS । यह है कि कैसे आप जानते हैं कि आपके कंप्यूटर पर एक पोर्ट अनुपयोगी है (किसी अन्य प्रक्रिया द्वारा, दूसरे शब्दों में उपयोग किया जाता है)।

हालाँकि, आपके मामले में, आपको अपने श्रोता के लिए एक एकल हार्ड-कोडेड पोर्ट का उपयोग करने में कोई समस्या नहीं होनी चाहिए, जब तक कि आप एक त्रुटि संदेश प्रिंट नहीं करते हैं जब बाइंड विफल हो जाता है।

यह भी ध्यान दें कि आपके अधिकांश सॉकेट (दासों के लिए) को विशिष्ट पोर्ट संख्याओं के लिए स्पष्ट रूप से बाध्य होने की आवश्यकता नहीं है - केवल सॉकेट्स जो आने वाले कनेक्शनों की प्रतीक्षा करते हैं (जैसे कि आपके मास्टर की तरह) को एक श्रोता और बंदरगाह के लिए बाध्य करने की आवश्यकता होगी। यदि पोर्ट का उपयोग करने से पहले सॉकेट के लिए निर्दिष्ट नहीं किया गया है, तो ओएस सॉकेट के लिए एक प्रयोग करने योग्य पोर्ट असाइन करेगा। जब मास्टर एक गुलाम को जवाब देना चाहता है जो इसे डेटा भेजता है, तो श्रोता का पता सुलभ होता है जब श्रोता डेटा प्राप्त करता है।

मुझे लगता है कि आप इसके लिए यूडीपी का उपयोग करेंगे?


0

यदि आपको केवल बाद के उपयोग के लिए एक मुफ्त पोर्ट खोजने की आवश्यकता है, तो यहां पिछले उत्तर के समान एक स्निपेट है , लेकिन कम, सॉकेट्वर का उपयोग करके :

import socketserver

with socketserver.TCPServer(("localhost", 0), None) as s:
    free_port = s.server_address[1]

ध्यान दें कि बंदरगाह मुक्त रहने की गारंटी नहीं है, इसलिए आपको इस स्निपेट और कोड को लूप में उपयोग करने की आवश्यकता हो सकती है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.