2012-02-11 14 views
6

पर एकाधिक मल्टीकास्ट समूहों की सदस्यता लेना क्या एक एकल सॉकेट पर एक से अधिक मल्टीकास्ट समूह से डेटा प्राप्त करना संभव है?एक सॉकेट (लिनक्स, सी)

उदाहरण के लिए:

void AddGroup(int sock, 
       const char* mc_addr_str, 
       int mc_port, 
       const char* interface) { 
    struct sockaddr_in mc_addr; 
    memset(&mc_addr, 0, sizeof(mc_addr)); 
    mc_addr.sin_family  = AF_INET; 
    mc_addr.sin_addr.s_addr = inet_addr(mc_addr_str); 
    mc_addr.sin_port  = htons(mc_port); 

    if ((bind(sock, (struct sockaddr *) &mc_addr, 
      sizeof(mc_addr))) < 0) { 
    perror("bind() failed"); 
    exit(1); 
    } 

    // construct an IGMP join request structure 
    struct ip_mreq mc_req; 
    mc_req.imr_multiaddr.s_addr = inet_addr(mc_addr_str); 
    mc_req.imr_interface.s_addr = inet_addr(interface); 

    if ((setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, 
        (void*) &mc_req, sizeof(mc_req))) < 0) { 
    perror("setsockopt() failed"); 
    exit(1); 
    } 
} 

जब मैं एक बहुस्त्र्पीय समूह जोड़ने के इस कोड काम करता है। लेकिन जब मैं एक और जोड़ने की कोशिश करता हूं, तो "बाध्य" विफल रहता है। मुझे समझ में नहीं आता कि बांध को पहले स्थान पर क्यों होना चाहिए? (लेकिन कोड इसके बिना काम नहीं करता है)।

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

उत्तर

3

आप केवल एक बार सॉकेट बांधते हैं। दूसरी बार बांधें और देखें कि क्या होता है।

-3

मुझे विश्वास नहीं है कि किसी दिए गए सॉकेट पर एक से अधिक मल्टीकास्ट समूह में शामिल होना संभव है। सॉकेट को स्रोत आईपी/पोर्ट और गंतव्य आईपी/पोर्ट की जोड़ी द्वारा परिभाषित किया जाता है। ऑपरेटिंग सिस्टम को पता नहीं चलेगा कि दूसरे आईपी/पोर्ट से नीचे आने वाले डेटा के साथ क्या करना है क्योंकि इसमें इसे भेजने के लिए सॉकेट नहीं होगा।

ऑपरेटिंग सिस्टम के साथ कनेक्शन पंजीकृत करने के लिए बाध्य आवश्यक है। यह मूल रूप से एक फाइल हैंडल पंजीकृत करने की तरह है।

ऐसा करने का सबसे अच्छा तरीका प्रत्येक मल्टीकास्ट समूह के लिए सॉकेट बनाना होगा और फिर चयन() को कॉल करना होगा। चुनें() आपको सूचित करेगा अगर किसी सॉकेट में डेटा पढ़ने के लिए तैयार है।

सॉकेट(), बाइंड(), और चयन() पर अधिक जानकारी के लिए अपने मैन पेजों की जांच करें।

+2

आप सही नहीं हैं तैयार करने के बारे ख्याल रखना चाहिए। आप जितने चाहें उतने समूहों में शामिल हो सकते हैं। मल्टीकास्ट समूहों में शामिल होने के लिए पहचानने वाले टुपल से कोई लेना देना नहीं है। – EJP

6

बाइंड() के बजाय IP_ADD_MEMBERSHIP विकल्प के साथ उपयुक्त setsockopt() कॉल का उपयोग करके आप जितने चाहें उतने मल्टीकास्ट समूहों में शामिल हो सकते हैं।

+0

जब मैं AddGroup के बाद की कॉल पर "बाइंड" को हटा देता हूं, तो केवल पहले मल्टीकास्ट समूह को "सब्सक्राइब किया गया" लगता है। – Switch

+0

@Switch यदि कोई समूह आपके डिफ़ॉल्ट आईपी रूट के माध्यम से पहुंच योग्य नहीं है तो आपको समूह में शामिल होने पर उचित आउटबाउंड स्थानीय पता निर्दिष्ट करने की आवश्यकता है, इसलिए 'सदस्यता जोड़ें' IGMP संदेश अप्रिय दिशा में जाता है। – EJP

2

bind निष्क्रिय पते पर, यानी आईपीवी 4 के लिए 0.0.0.0 और अतिरिक्त समूहों में खींचने के लिए एएसएम या एसएसएम का उपयोग करें, उदा। सूचीबद्ध के रूप में IP_ADD_MEMBERSHIP

आप केवल bind एक बार कर सकते हैं।

2

आप एक ही सॉकेट पर जितने मल्टीकास्ट समूह में शामिल हो सकते हैं। Setockopt(), IP_PKTINFO को यह जानने के लिए देखें कि आप किस मल्टीकास्ट समूह से डेटा पढ़ रहे हैं।

0

हाँ, यह संभव है: लिंक (http://www.tenouk.com/Module41c.html) में उदाहरण पर देखने के कुछ चरणों में इस अप छोटा करने के लिए:

  1. आप SO_REUSEADDR साथ setsockopt
  2. आप बाँध INADDR_ANY पर
  3. आप प्रत्येक समूह पर IP_ADD_MEMBERSHIP के साथ setockopt जिसे आप डेटाग्राम प्राप्त करना चाहते हैं।
  4. मुझे ऐसा लगता है कि IP_PKTINFO का उपयोग कर प्राप्त पैकेट भेद करने के लिए एक विकल्प देता है, लेकिन इस के लिए उन्हें (Setting the source IP for a UDP socket)
संबंधित मुद्दे