2012-01-12 19 views
10

के लिए यादृच्छिक बंदरगाह प्राप्त करें मुझे एक ऐसा प्रोग्राम बनाना होगा जो यूडीपी सॉकेट के माध्यम से उसी कंप्यूटर पर अन्य प्रोग्रामों के साथ संवाद करेगा। यह stdin से कमांड पढ़ेगा, और इनमें से कुछ आदेश निष्पादन को रोकने के बिना पैकेट भेजने/प्राप्त करने के लिए बनाएंगे। मैं वहां कुछ जानकारी पढ़ चुके हैं, लेकिन जब से मैं सॉकेट प्रोग्रामिंग से परिचित नहीं हूँ और यह जल्दी से कर पाने की जरूरत है, मैं निम्नलिखित प्रश्न हैं:यूडीपी सॉकेट

  1. मैं इस कार्यक्रम के लिए एक यादृच्छिक अप्रयुक्त बंदरगाह प्राप्त करने की आवश्यकता सुनने के लिए, और इसे आरक्षित करें ताकि अन्य कार्यक्रम इस के साथ संवाद कर सकें और बंदरगाह किसी अन्य कार्यक्रम द्वारा आरक्षित नहीं है। मुझे भविष्य के उपयोग के लिए एक चर पर पोर्ट नंबर को स्टोर करने की भी आवश्यकता है।
  2. चूंकि संचार उसी मशीन पर प्रक्रियाओं में है, इसलिए मुझे आश्चर्य है कि क्या मैं PF_LOCAL का उपयोग कर सकता हूं।

इस तरह के सॉकेट के सेटअप का एक कोड नमूना भी स्वागत होगा, साथ ही चरित्र तारों को भेजने/प्राप्त करने का एक उदाहरण भी होगा।

+0

किस मंच के लिए? –

+0

स्टैंडर लाइब्रेरी का उपयोग कर लिनक्स ओएस – rabusmar

+1

सॉकेट का उपयोग करके प्रक्रियाओं के बीच संवाद क्यों करें? क्या यह सिर्फ ऐसा करने के लिए है?;) – BlackBear

उत्तर

20

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

srand(time(NULL)); 
rand() % NUM_PORTS; // NUM_PORTS isn't a system #define 

:

+0

यह करने का यह एक अच्छा तरीका है लेकिन यह निश्चित रूप से ऐसा करने का एक यादृच्छिक तरीका नहीं होगा। – dbeer

+1

मुझे लगता है कि यदि आप वास्तव में यादृच्छिक बंदरगाह चाहते थे, तो आप बाध्य सफलता प्राप्त होने तक ((रैंड()% 65535) +1 से जुड़ने की कोशिश कर सकते हैं। – selbie

+2

यह यादृच्छिक होगा कि आपको पता नहीं चलेगा कि बाध्यकारी सफल होने तक बंदरगाह क्यों चुना जाता है। बंदरगाह 0 के लिए बाध्यकारी ओएस को पहले उपलब्ध अप्रयुक्त बंदरगाह को चुनने की अनुमति देता है। यदि 'बाइंड() 'सफल होता है, तो आपको एक बंदरगाह रखने के लिए गारेट किया जाता है जिसका उपयोग केवल आपके द्वारा किया जा रहा है और कोई और नहीं। आपकी निर्दिष्ट आवश्यकताओं को इसे वास्तव में यादृच्छिक persay, केवल अद्वितीय होने की आवश्यकता नहीं है, और यह होगा। –

0

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

+1

आपको ट्रैक करना होगा कि आपने किन बंदरगाहों का प्रयास किया है ताकि आप पहली बार विफल होने के बाद उनसे जुड़ने की कोशिश न करें। –

+0

सच है, हालांकि खुली बंदरगाह खोजने से पहले छद्म-यादृच्छिक अनुक्रम में बंदरगाहों को दोहराना संभावना बहुत कम है। – dbeer

1

रेमी लेबेउ द्वारा उत्तर अच्छा है यदि आपको अस्थायी बंदरगाह की आवश्यकता है यदि आपको लगातार आरक्षित बंदरगाह की आवश्यकता है तो यह बहुत अच्छा नहीं है क्योंकि अन्य सॉफ़्टवेयर पोर्ट को प्राप्त करने के लिए एक ही विधि का उपयोग करता है (जिसमें ओएस टीसीपी स्टैक भी शामिल है जिसमें प्रत्येक कनेक्शन के लिए एक नए अस्थायी बंदरगाह की आवश्यकता होती है)।

तो निम्न हो सकता है :, तो मैं बचाने

    1. आप एक बंदरगाह पाने के लिए 0 और getsockname() के साथ बाँध फोन भविष्य में उपयोग के लिए कॉन्फ़िगरेशन (या कई कॉन्फ़िगरेशन में) में टी;
    2. सॉफ़्टवेयर जो इस पोर्ट की आवश्यकता है उसे बंदरगाह से शुरू होता है और बांधता है।

    फिर आपको उदा। सॉफ़्टवेयर को पुनरारंभ करें:

    1. सॉफ़्टवेयर बंद हो जाता है और पोर्ट को अनबिंड करता है: पोर्ट को अब बाइंड (0) और getockname() से वापस किया जा सकता है;
    2. उदा। टीसीपी स्टैक को एक बंदरगाह की आवश्यकता होती है और आपके बंदरगाह को बांधती है;
    3. सॉफ़्टवेयर प्रारंभ नहीं हो सकता है क्योंकि पोर्ट पहले ही बाध्य है।

    तो "भविष्य के उपयोग" के लिए आपको एक बंदरगाह की आवश्यकता है जो क्षणिक बंदरगाह सीमा में नहीं है (वह सीमा है जिसमें से बांध (मेजबान, 0) एक बंदरगाह देता है)।

    इस समस्या के लिए मेरा समाधान port-for कमांड-लाइन उपयोगिता है।

  • +2

    बहुत ही कम, यदि कभी भी, आपको पहली बार एक क्षणिक बंदरगाह को पुनः प्राप्त करने की आवश्यकता होगी और इसे बाद के कनेक्शन में पुन: उपयोग के लिए सहेजने की आवश्यकता होगी। मैं 10 से अधिक वर्षों के लिए सॉकेट कोड लिख रहा हूं और कभी ऐसा करने की आवश्यकता नहीं है, एक बार नहीं। आम तौर पर, आप या तो हर समय क्षणिक बंदरगाहों का उपयोग करेंगे (और सर्वर के लिए, उस पोर्ट को गतिशील रूप से खोजने का एक तरीका प्रदान करें), या उपयोगकर्ता को आपके ऐप की कॉन्फ़िगरेशन में एक निश्चित पोर्ट निर्दिष्ट करें, जिस स्थिति में उपयोगकर्ता सुनिश्चित करता है कि बंदरगाह हमेशा के लिए उपलब्ध है उपयोग। –

    +0

    यदि प्रश्न की मेरी समझ सही है (esp। "1" भाग), तो यह इसके लिए पूछता है। हालांकि यह मामला नहीं हो सकता है। उपयोग का मामला यह सुनिश्चित करने के लिए नहीं है कि बंदरगाह हमेशा उपलब्ध है लेकिन एक सॉफ्टवेयर बनाने के लिए बंदरगाह उपलब्ध है। –

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