तो मैंने कुछ परीक्षण किया। मेरे परिणामों के आधार पर, यह स्पष्ट है कि वे अंतर्निहित ओएस कार्यान्वयन पर निर्भर करते हैं। संदर्भ के लिए, मैंने इसे स्टॉक फेडोरा कर्नेल के साथ परीक्षण किया: 2.6.35.10-74.fc14.x86_64
।
लब्बोलुआब यह है कि async_resolve()
केवल इस मामले में जहां आप एक deadline_timer
की स्थापना के बिना दूर प्राप्त करने में सक्षम हो सकता है होना करने के लिए लग रहा है है। यह उचित व्यवहार के लिए हर दूसरे मामले में व्यावहारिक रूप से आवश्यक है।
async_resolve()
async_resolve()
को एक कॉल 5 सेकंड के अलावा 4 प्रश्नों में हुई। boost::asio::error::host_not_found
त्रुटि के अनुरोध के बाद हैंडलर को 20 सेकंड कहा गया था।
2 प्रयत्न (resolv.h
) के साथ 5 सेकंड के एक समय समाप्ति मेरे समाधानकर्ता चूक है, तो ऐसा लगता है के लिए कॉन्फ़िगर प्रश्नों के दो बार संख्या भेजने के लिए। व्यवहार options timeout
और options attempts
/etc/resolv.conf
में सेट करके संशोधित है। प्रत्येक मामले में भेजे गए प्रश्नों की संख्या दोगुनी थी जो attempts
को सेट किया गया था और हैंडलर को बाद में host_not_found
त्रुटि के साथ बुलाया गया था।
परीक्षण के लिए, एकल कॉन्फ़िगर किया गया नेमसर्वर ब्लैक-होल रूट किया गया था।
async_connect()
एक ब्लैक होल से कराई गंतव्य के साथ async_connect()
कॉलिंग हैंडलर ~ 189 सेकंड के बाद त्रुटि boost::asio::error::timed_out
साथ बुलाया जा रहा है के परिणामस्वरूप।
ढेर ने प्रारंभिक SYN और 5 रीट्री भेजीं। पहली बार पुनः प्रयास 3 सेकंड के बाद भेजा गया था, प्रत्येक बार दोबारा रेट्री टाइमआउट (3 + 6 + 12 + 24 + 48 + 96 = 18 9)। पुनर्प्रयास की संख्या बदला जा सकता है:
% sysctl net.ipv4.tcp_syn_retries
net.ipv4.tcp_syn_retries = 5
5 के डिफ़ॉल्ट RFC 1122 (4.2.3.5) के साथ पालन करने के लिए चुना जाता है: एक SYN खंड के लिए
[पुनर्संचरण टाइमर] होना चाहिए पर पर्याप्त रूप से सेट करें, कम से कम 3 मिनट के लिए सेगमेंट के पुन: ट्रांसमिशन प्रदान करें। एप्लिकेशन कनेक्शन (यानी, खुले प्रयास पर छोड़ दें) जल्द से जल्द बंद कर सकता है।
3 मिनट = 180 सेकंड, हालांकि आरएफसी ऊपरी बाउंड निर्दिष्ट नहीं करता है। हमेशा के लिए पुनः प्रयास करने से कार्यान्वयन रोकने के लिए कुछ भी नहीं है।
async_write()
जब तक सॉकेट के भेजने बफर पूर्ण नहीं था, इस हैंडलर हमेशा उसी समय कहा जाता था।
मेरी परीक्षा ने एक टीसीपी कनेक्शन स्थापित किया और एक मिनट बाद async_write()
पर कॉल करने के लिए टाइमर सेट किया। मिनट जहां कनेक्शन स्थापित किया गया था लेकिन async_write()
कॉल करने से पहले के दौरान, मैं हाथापाई के सभी प्रकार की कोशिश की:
- गंतव्य के लिए ब्लैक होल बाद यातायात के लिए एक नीचे की ओर रूटर की स्थापना।
- सत्र को डाउनस्ट्रीम फ़ायरवॉल में साफ़ करना ताकि यह गंतव्य से खराब आरएसटी के साथ जवाब दे सके।
- मेरी ईथरनेट
/etc/init.d/network stop
चल रहा है कोई फर्क नहीं पड़ता कि मैं क्या किया अनप्लग, अगले async_write()
तुरंत सफलता रिपोर्ट करने के लिए अपने हैंडलर कॉल करेगा।
मामले में जहां फ़ायरवॉल जाली आरएसटी में, कनेक्शन तुरंत बंद हो गया है, लेकिन मैं जानने का कोई तरीका था कि जब तक मैं अगले आपरेशन का प्रयास किया है (जो तुरंत boost::asio::error::connection_reset
रिपोर्ट करेंगे)। अन्य मामलों में, कनेक्शन खुला रहेगा और जब तक यह अंततः 17-18 मिनट बाद समाप्त नहीं हो जाता तब तक त्रुटियों की रिपोर्ट न करें।
async_write()
के लिए सबसे खराब मामला यह है कि यदि मेजबान पुन: प्रेषण कर रहा है और प्रेषण बफर भरा हुआ है।यदि बफर भरा हुआ है, तो async_write()
रीट्रांसमिशन समय समाप्त होने तक अपने हैंडलर को कॉल नहीं करेगा। 15 पुनर्संचरण को लिनक्स चूक:
% sysctl net.ipv4.tcp_retries2
net.ipv4.tcp_retries2 = 15
समय पुनर्संचरण के बीच (जैसे विशिष्ट कनेक्शन की अनुमानित राउंड ट्रिप समय के रूप में और कई कारकों पर आधारित है) प्रत्येक के बाद बढ़ जाती है लेकिन 2 मिनट में जोड़ा जाता है। तो डिफ़ॉल्ट 15 रीट्रांसमिशन और सबसे खराब-केस 2-मिनट का टाइमआउट के साथ, async_write()
हैंडलर के लिए ऊपरी बाउंड 30 मिनट है। जब इसे कहा जाता है, तो त्रुटि boost::asio::error::timed_out
पर सेट की जाती है।
async_read()
यह जब तक कनेक्शन स्थापित हो जाने और कोई डेटा प्राप्त होता है अपने हैंडलर फोन कभी नहीं करना चाहिए। मेरे पास इसका परीक्षण करने का समय नहीं है।
मुझे अपनी खुद की 'deadline_timer' बनाने के लिए भी चिपकना पड़ा, इसलिए मुझे यह देखने में बहुत दिलचस्पी होगी कि यह अनावश्यक है या नहीं। – chrisaycock
+1 दिलचस्प सवाल है। मुझे लगता है कि जवाब काफी हद तक मंच निर्भर होगा। मुझे लगता है कि आप लिनक्स के बारे में परवाह करते हैं? –