2010-03-02 17 views
6

पर प्रसारण अनुरोध के जवाब में एन संख्या से ग्राहकों से प्रतिक्रिया प्राप्त करना मैं एक विशेष प्रकार के नेटवर्क मल्टीमीडिया डिवाइस के लिए एक प्रकार का आईपी खोजक लागू कर रहा हूं। मैं अपने आईपी पते और अन्य विवरण के साथ लैन में उस प्रकार के सभी जीवित डिवाइसों को जानना चाहता हूं।यूडीपी

डिवाइस का डिवाइस खोज का अपना तरीका है।

यह निम्नानुसार कार्य करता है: एक ग्राहक यूडीपी के माध्यम से लैन पर प्रसारण अनुरोध भेजता है।
गंतव्य पोर्ट नंबर तय किया गया है।
उत्तर में, इस अनुरोध के प्रारूप को समझने वाले लैन के सभी सर्वर इस अनुरोध का जवाब देंगे कि वे अपने बारे में जानकारी प्रदान करें।

मैं sendto() का उपयोग कर यूडीपी अनुरोध संदेश प्रसारित कर रहा हूं।

अब मेरी समस्या यह है कि मुझे नहीं पता कि कितने डिवाइस (i.e.servers) अनुरोध का जवाब देंगे।

मुझे कितनी बार recvfrom() कॉल करना होगा?
मुझे कब पता चलेगा कि मैंने सभी उपकरणों से प्रतिक्रिया संभाली है?
या सामान्य रूप से, कई सर्वरों से प्रतिक्रिया प्राप्त करने के लिए सही विकल्प() सही है?
क्या कोई बेहतर है (या अगर मैं यहां गलत हूं) तो इसे पूरा करने का तरीका क्या है?

मैं सी/सी ++ में प्रोग्रामिंग कर रहा हूं, विंडोज और लिनक्स दोनों के लिए कोड बनाने की योजना बना रहा हूं।
अग्रिम में बहुत धन्यवाद।

संपादित करें: तो सभी नेटवर्क प्रोग्रामिंग की मदद से यहाँ से बाहर जादूगरों
का चयन करें() मेरे लिए सिर्फ बात है ...
धन्यवाद करने के लिए एक बहुत, मैं मेरी समस्या का हल मिल गया है :) आप सभी ने मेरी मदद करने के लिए समय निकाला

+0

मुझे लगता है कि खोज चरण के बाद आप इन उपकरणों से संवाद करना चाहते हैं? शुरुआत से आईपी मल्टीकास्ट का उपयोग क्यों न करें (http://en.wikipedia.org/wiki/Multicast देखें)? –

+0

सर्वर फर्मवेयर में लागू किया गया है। मेरे पास डिवाइस निर्माता द्वारा निर्धारित प्रोटोकॉल का पालन करने के अलावा कोई विकल्प नहीं है।मुझे यूडीपी पर अनुरोध प्रसारित करना है :( – puffadder

+0

यह वास्तव में मुझे 'यूपीएनपी' या 'यूनिवर्सल प्लग एंड प्ले' के बारे में सोचता है, http://fr.wikipedia.org/wiki/Universal_Plug_and_Play –

उत्तर

2

मुझे कितनी बार recvfrom() कॉल करना होगा? मुझे कब पता चलेगा कि मैंने सभी उपकरणों/सर्वर से प्रतिक्रिया संभाली है?

आप उपकरणों/सर्वरों की संख्या पता नहीं है, तो आप पता नहीं कर सकते हैं कि कितनी बार आप या recvfrom() को कॉल करना होगा आप सभी प्रतिक्रियाओं संभाला है जब।

आप select() लूप (टाइमआउट तक) का उपयोग करने पर विचार कर सकते हैं और recvfrom() पर कॉल करने के लिए डेटा उपलब्ध होने पर कॉल कर सकते हैं। यह मुख्य धागे या एक अलग थ्रेड में हो सकता है।

यदि डेटा संसाधित होने से तेज़ी से आता है, तो आप डेटाग्राम खो देंगे। यह मोटे तौर पर उस गति पर निर्भर करेगा कि डेटा को पार्स किया जाता है और प्राप्त होने के बाद संग्रहीत किया जाता है। यदि डेटा को प्रोसेस करना एक गहन ऑपरेशन है, तो प्रसंस्करण को अलग थ्रेड में करना आवश्यक हो सकता है या डेटा को तब तक स्टोर करना आवश्यक हो जाता है जब तक कि लूप टाइम प्राप्त न हो और फिर इसे प्रोसेसिंग के साथ आगे बढ़ें।

चूंकि यूडीपी अविश्वसनीय है, कुछ बार पुन: प्रसारण करने के लिए लूपिंग कुछ नुकसान के लिए खाते में मदद करनी चाहिए और प्रसंस्करण को डुप्लिकेट के लिए जिम्मेदार होना चाहिए।

निम्नलिखित स्यूडोकोड कैसे मैं इस समस्या तक पहुंचने की संभावना है:


/* get socket to receive responses */ 
sd = socket(...); 

do 
{ 
    /* set receive timeout */ 
    timeout.tv_sec = 5;  

    /* broadcast request */ 
    sendto(...); 

    /* wait for responses (or timeout) */ 
    while(select(sd+1, &readfds, NULL, NULL, &timeout) > 0) 
    { 
     /* receive the response */ 
     recvfrom(...); 

     /* process the response (or queue for another thread/later processing) */ 
     ... 

     /* reset receive timeout */ 
     timeout.tv_sec = 5; 
    } 

    /* process any response queued for later (and not another thread) */ 

} while (necessary); 

या सामान्य रूप में, recvfrom() कई सर्वरों से प्रतिक्रिया प्राप्त करने के लिए सही विकल्प है?

recvfrom() आमतौर पर संयोजन मोड सॉकेट के साथ प्रयोग किया है क्योंकि यह प्राप्त आंकड़ों का स्रोत पता पुनः प्राप्त करने के आवेदन की अनुमति देता है है।

+1

यदि सभी सर्वर प्रतिक्रिया देंगे एक ही समय में, इसे कैसे संभाला जाएगा? – puffadder

+0

प्रतिक्रिया के लिए धन्यवाद। लेकिन क्या मुझे वास्तव में प्रत्येक प्रतिक्रिया को संसाधित करने के लिए धागे की आवश्यकता है? क्या कोई अन्य तरीका है? – puffadder

+0

प्रतिक्रियाओं में उत्तरदाताओं के आईपी पते और डिवाइस आईडी शामिल हैं, अन्य चीजों के साथ मैं प्रतिक्रियाओं को पार्स करना चाहता हूं और आवश्यक डेटा स्टोर करना चाहता हूं। – puffadder

2

एक लूप में टाइमआउट के साथ select(2)/poll(2) का उपयोग करें, हर बार जब आप किसी डिवाइस से प्रतिक्रिया प्राप्त करते हैं तो टाइमआउट को कम करें। आपको उचित समय-समय पर स्वयं के साथ आना होगा।

वैकल्पिक रूप से, यदि आप खोज प्रतिक्रिया संदेश को पहचान/पार्स करने में सक्षम हैं, तो इस तरह के संदेश प्राप्त करने के बाद बस डिवाइस को सूची में जोड़ें।

डिवाइस के पंजीकरण के दौरान आपको किसी भी समय टाइमआउट से निपटना होगा, लेकिन बाद में विफल हो जाएगा।

2

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

/* create and bind socket */ 

fd_set fds; 
struct timeval tv; 

tv.tv_sec = 2; 
tv.tv_usec = 0; 
FD_ZERO(&fds); 
FD_SET(sock, &fds); 
int ret; 

while((ret = select(sock + 1, &fds, NULL, NULL, &tv)) > 0) { 
    char buf[BUFLEN]; 
    struct sockaddr addr; 

    if(recvfrom(sock, buf, BUFLEN, MSG_DONTWAIT, &addr, sizeof(struct sockaddr)) > 0) { 
     /* handle response */ 
    } else { 
     /* handle error */ 
    }   
} 
if(ret < 0) { 
    /* handle error */ 
} else { 
    /* select() timed out; we're theoretically done */ 
} 

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

+0

क्या मुझे चुनिंदा फ़ंक्शन का उपयोग करने के लिए "बाध्य" जरूरी है? वर्तमान में मैं सॉकेट बाध्य नहीं कर रहा हूं ... – puffadder

+0

@pufadder - नहीं, आपको 'बांधने' की आवश्यकता नहीं है। 'select()' फ़ाइल डिस्क्रिप्टर का एक सेट लेता है, और जब आप सॉकेट बनाते हैं तो सेट में जोड़ने के लिए आपको एक फ़ाइल डिस्क्रिप्टर प्राप्त होगा। – jschmier

+0

भले ही आप जानते हों कि कितने सर्वर जवाब देने जा रहे थे, आप नहीं जानते कि आप कितने संदेश प्राप्त करने जा रहे हैं। रास्ते में कुछ पैकेट गिराए जा सकते हैं। – nos

0

आप नहीं जान सकते हैं। यह अनजान है।

संभवतः, आपके विवरण से: I want to find out all the alive devices, डिवाइस मृत से जिंदा में परिवर्तित हो सकते हैं और जब भी वे चाहते हैं, फिर से वापस आ सकते हैं। इसका मतलब है कि आपको निरंतर मतदान करना होगा: यानी प्रत्येक कुछ सेकंड (लेकिन अक्सर नहीं) प्रसारण अनुरोध भेजें और देखें कि कौन जवाब देता है।

  • , हर कुछ सेकंड बाहर प्रसारित भेजें उपकरणों के बाद से:

    मैं यह अधिकार मिल गया है, कि यूडीपी स्वाभाविक अविश्वसनीय है, तो आप यूडीपी के शीर्ष पर कुछ विश्वसनीयता रेट्रो फिट करने के लिए जा रहे हैं इसे हर बार प्राप्त नहीं हो सकता है।

  • आपको उनके उत्तर प्राप्त नहीं हो सकते हैं, लेकिन आप अगली बार हो सकते हैं।
  • एक उत्तर पुष्टि करता है कि डिवाइस जीवित है।
  • डिवाइस को मृत घोषित करने से पहले 'एन' गैर-प्रतिक्रियाओं की प्रतीक्षा करें।

क्या आप संभावित उपकरणों की अधिकतम संख्या जानते हैं? यदि आप करते हैं तो आपको लगता है कि आपको कई बार recvfrom() को कॉल करना होगा।

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