2013-05-02 7 views
5

मैं recvmmsg() का उपयोग करके सी का उपयोग करके एक सरल अनुप्रयोग बनाता हूं, और पांचवां पैरामीटर type struct timespec का समय समाप्ति है। मैंने टाइमआउट को 5 सेकंड तक सेट किया है, लेकिन यह काम नहीं कर रहा है, यह अनंतता को अवरुद्ध कर देता है।recvmmsg() में टाइमआउट कैसे सेट करें?

कोड के रूप में है निम्नलिखित:

struct timespec timeout; 

timeout.tv_sec = 5; 
timeout.tv_nsec = 0; 

result = recvmmsg(fd, datagrams, BATCH_SIZE, 0, &timeout); 
+1

यहां संभावित बग का एक सुझाव दिया गया है जो प्रासंगिक हो सकता है: http://lists.openwall.net/netdev/2012/12/23/30 – Vicky

+0

@ विकी: यह सही है - मेरे लिंक में इसी तरह जवाब। हालांकि यह स्पष्ट नहीं है कि कोई भी व्यवहार को बदलने जा रहा है - अधिक संभावना है कि इसे एक दस्तावेज बग माना जाएगा, मैन पेज अपडेट किया जाएगा, और निकट-बेकार टाइमआउट पैरामीटर का उपयोग ज्यादातर अनुप्रयोगों द्वारा नहीं किया जाएगा। –

+0

चयन का उपयोग कर उपरोक्त लिंक में एक और समाधान है: http://stackoverflow.com/questions/12713438/how-to-add-delay-to-sento-and-recvfrom-in-udp-client-server-in- सी – MOHAMED

उत्तर

4

का उपयोग करना चाहिए एक विकल्प के रूप में, आप SO_RCVTIMEO विकल्प के साथ setsockopt इस्तेमाल कर सकते हैं पर एक समय समाप्ति सेट करने के लिए सॉकेट। यह उस पर किए गए सभी पढ़ने के कार्यों को प्रभावित करेगा।

5

यहाँ देखें: http://permalink.gmane.org/gmane.linux.man/3440

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

+0

मैं वास्तव में एक उपयोगकेस की कल्पना नहीं कर सकता जहां यह उपयोगी और इरादा है। – PlasmaHH

+0

इस उत्तर के लिंक से, मुझे एक बहुत ही दृष्टांत होने के लिए एक उद्धरण मिला है "recvmmsg() में एक स्पष्ट टाइमआउट पैरामीटर है लेकिन ऐसा नहीं लगता है कि यह ठीक से काम करता है और दस्तावेज़ीकरण का उल्लेख नहीं है कि इसे SO_RCVTIMEO के साथ कैसे बातचीत करना है। " यह सहायक था क्योंकि यह बताता है कि आपको सॉकेट के 'SO_RCVTIMEO' पैरामीटर को क्यों सेट करना होगा यदि आप 'recvmmsg()' टाइमआउट पैरामीटर अनिश्चित काल तक अवरुद्ध नहीं करना चाहते हैं। (मेरा recvmmsg परीक्षण कोड ('man recvmmsg' से) 1 सेकंड के टाइमआउट के साथ अनिश्चित काल तक ब्लॉक करता है। यदि आप सॉकेट के SO_RCVTIMEO सेट करते हैं, तो यह अनिश्चित काल तक अवरुद्ध नहीं होता है।) –

0

वहाँ recvmmsg कार्यान्वयन में बग है:

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

मेरा सुझाव है कि आप SO_RCVTIMEO का उपयोग timeout recvmmsg के पैरामीटर में जोड़ें। अगर SO_RCVTIMEO या timeout के बाद कोई डेटा प्राप्त नहीं हुआ तो recvmmsg बाहर निकल जाएगा। सबसे बुरे मामले में, recvmmsg timeout + SO_RCVTIMEO के बाद बाहर निकल जाएगा (जहां timeout के अंत से पहले डेटा प्राप्त होता है और कोई डेटा नहीं आता है)।

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