2012-07-18 19 views
6

प्राप्त करने में असफल रहा मुझे कुछ के साथ समस्या है और मुझे लगता है कि यह कोड है।पायथन यूडीपी सॉकेट अर्ध-यादृच्छिक रूप से

एप्लिकेशन का उपयोग कुछ कस्टम किए गए नेटवर्क उपकरणों को 'पिंग' करने के लिए किया जाता है ताकि यह जांच सके कि वे जीवित हैं या नहीं। यह उन्हें एक विशेष यूडीपी पैकेट के साथ हर 20 सेकंड में पिंग करता है और प्रतिक्रिया की अपेक्षा करता है। अगर वे लगातार 3 पिंग्स का जवाब देने में असफल होते हैं तो एप्लिकेशन कर्मचारियों को चेतावनी संदेश भेजता है।

एप्लिकेशन 24/7 चल रहा है और दिन में यादृच्छिक संख्या (2-5 अधिकतर) के लिए एप्लिकेशन 10 मिनट के सटीक समय के लिए यूडीपी पैकेट प्राप्त करने में विफल रहता है, जिसके बाद सब कुछ सामान्य हो जाता है। उन 10 मिनट के दौरान केवल 1 डिवाइस का जवाब देने लगता है, अन्य लोग मरते हैं। कि मैं लॉग से कटौती करने में सक्षम हूं।

मैं wireshark का उपयोग किया है पैकेट सूंघ करने के लिए और मैं सत्यापित किया है कि पिंग पैकेट जा रहे हैं दोनों बाहर और में,, ओएस के लिए सभी तरह से तो नेटवर्क हिस्सा ठीक काम कर रहा है। कंप्यूटर WinXPPro चला रहे हैं और कुछ को फ़ायरवॉल कॉन्फ़िगर नहीं किया गया है। मुझे यह समस्या विभिन्न कंप्यूटरों, विभिन्न विंडोज़ इंस्टॉल और विभिन्न नेटवर्क पर है।

मुझे वास्तव में नुकसान हो रहा है कि यहां समस्या क्या हो सकती है।

मैं कोड के प्रासंगिक भाग को जोड़ रहा हूं जो सभी नेटवर्क करता है। यह शेष आवेदन से अलग धागे में चलाया जाता है।

मैं जो भी अंतर्दृष्टि प्रदान कर सकता हूं, उसके लिए मैं आपको अग्रिम धन्यवाद देता हूं।

def monitor(self): 
    checkTimer = time() 
    while self.running: 
     read, write, error = select.select([self.commSocket],[self.commSocket],[],0) 
     if self.commSocket in read: 
      try: 
       data, addr = self.commSocket.recvfrom(1024) 
       self.processInput(data, addr) 
      except: 
       pass 

     if time() - checkTimer > 20: # every 20 seconds 
      checkTimer = time() 
      if self.commSocket in write: 
       for rtc in self.rtcList: 
        try: 
         addr = (rtc, 7) # port 7 is the echo port 
         self.commSocket.sendto('ping',addr) 
         if not self.rtcCheckins[rtc][0]: # if last check was a failure 
          self.rtcCheckins[rtc][1] += 1 # incr failure count 
         self.rtcCheckins[rtc][0] = False # setting last check to failure 
        except: 
         pass 

     for rtc in self.rtcList: 
      if self.rtcCheckins[rtc][1] > 2: # didn't answer for a whole minute 
       self.rtcCheckins[rtc][1] = 0 
       self.sendError(rtc) 
+0

मत भूलना कि यूडीपी विश्वसनीय trasmission की गारंटी नहीं देता: http://en.wikipedia.org/wiki/User_Datagram_Protocol –

+0

मुझे लगता है कि के बारे में पता है, लेकिन पुराने सिस्टम यहां 15 साल या ऐसा करने के लिए यूडीपी उपयोग कर रहा है काफी मज़बूती से और बाकी के सिस्टम में ऐसे कोई मुद्दे नहीं हैं। – flowInTheDark

उत्तर

3

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

फिर आपको उत्तरदायित्व के लिए यूडीपी सॉकेट की जांच करने की आवश्यकता नहीं है - यह हमेशा लिखने योग्य होता है।

अब असली समस्या के लिए - आप कह रहे हैं कि पैकेट सिस्टम में प्रवेश कर रहे हैं, लेकिन आपका कोड उन्हें प्राप्त नहीं करता है। यह शायद सॉकेट प्राप्त बफर के अतिप्रवाह के कारण है। पिछले 15 वर्षों में पिंग लक्ष्यों की संख्या में वृद्धि हुई है? आप अपने आप को एक पिंग-प्रतिक्रिया तूफान के लिए स्थापित कर रहे हैं, और शायद उन प्रतिक्रियाओं को पर्याप्त तेज़ी से नहीं पढ़ रहे हैं, इसलिए वे प्राप्त बफर में ढेर हो जाते हैं और अंततः गिराए जाते हैं।

लागत पर लाभ के क्रम में मेरे सुझाव:

  • पिंग अनुरोध फैले बाहर, अपने आप को निर्धारित नहीं करते हैं एक DDOS के लिए साइन अप। प्रश्न, प्रतिरक्षा एक प्रणाली, प्रति लक्ष्य अंतिम चेक समय रखें। यह आपको पैकेट की संख्या को बाहर और बाहर करने की अनुमति देगा।
  • SO_RCVBUF को एक बड़े मूल्य में बढ़ाएं।यह आपके नेटवर्क को पैकेट विस्फोटों के साथ बेहतर सौदा करने की अनुमति देगा।
  • एक पाश है, यानी एक बार अपने UDP सॉकेट पठनीय है में पढ़ें पैकेट (यह मानते हुए यह गैर अवरुद्ध है), पढ़ा जब तक आप EWOULDBLOCK मिलता है। यह आपको select() कॉल का गुच्छा बचाएगा।
  • देखें कि क्या आप लिनक्स recvmmsg(2) की लाइनों के साथ कुछ उन्नत विंडोज एपीआई का उपयोग कर सकते हैं, यदि ऐसी चीज मौजूद है, तो प्रत्येक सिस्कोल के एकाधिक पैकेट को डिस्काउंट करने के लिए।

आशा इस मदद करता है।

+0

वास्तव में सॉकेट अवरुद्ध मोड में था, लेकिन मेरे पास कुछ लॉगिंग हुई है जिसने पुष्टि की कि मुझे कभी भी समस्या नहीं थी। संभावित डीडीओएस के लिए, यह समस्या 4 उपकरणों के साथ-साथ 20 (जो हमारे पास सबसे बड़ी तैनाती प्रणाली है) के साथ सिस्टम में होती है, इसलिए मुझे यह विश्वास नहीं है कि यह एक डॉस का मामला है। मैं आपके सुझाव कोड में ले जाऊंगा और परिणामों के साथ वापस आऊंगा। धन्यवाद! – flowInTheDark

+0

बफर को बड़ा बनाना, अजीब रूप से पर्याप्त नहीं था। अंत में मदद क्या थी जब तक कि मैं इसे पठनीय नहीं कर पाता हूं, जब तक मैं एक लूप में सॉकेट को पढ़ने के लिए सुझाव नहीं देता। अब यह काम कर रहा है जैसा कि यह करना चाहिए। धन्यवाद! – flowInTheDark

0

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

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

टीएल; डॉ टीसीपी का उपयोग करें।

+1

कृपया उस पाठ का हिस्सा देखें जहां मैं अपने वायरशर्क स्नीफिंग का उल्लेख करता हूं और पुष्टि करता हूं कि पैकेट वास्तव में सिस्टम में प्रवेश करते हैं। – flowInTheDark

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