2009-10-02 14 views
14

मैं अपने परिचालन (पढ़ने/लिखने) को समझने से पहले कनेक्शन स्थिति को सत्यापित करना चाहता हूं।बढ़ावा :: asio :: ip :: tcp :: सॉकेट जुड़ा हुआ है?

क्या कनेक्ट है() विधि बनाने का कोई तरीका है?

मैंने this देखा, लेकिन ऐसा लगता है कि "बदसूरत"।

मैंने is_open() फ़ंक्शन का भी परीक्षण किया, लेकिन अपेक्षित व्यवहार नहीं है।

+0

संभावित डुप्लिकेट [कैसे जांचें कि Boost.Asio में सॉकेट बंद है या नहीं?] (Http://stackoverflow.com/questions/818665/how-to-check-if-socket-is-closed-in-boost -asio) – joshperry

उत्तर

28

टीसीपी मजबूत करने के लिए है अच्छी हालत में हैं एक कठोर नेटवर्क के चेहरे में; भले ही टीसीपी एक सतत अंत-टू-एंड कनेक्शन की तरह दिखता है, यह सब सिर्फ एक झूठ है, प्रत्येक पैकेट वास्तव में सिर्फ एक अद्वितीय, अविश्वसनीय डेटाग्राम है।

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

Virtual TCP Conduit

अंतर्निहित — स्वाभाविक संयोजन और अविश्वसनीय — नेटवर्क की प्रकृति के कारण

, ढेर केवल एक कटे हुए कनेक्शन रिपोर्ट दूरदराज के अंत एक फिन पैकेट भेजता है कनेक्शन बंद करने के लिए होगा, या यदि वह नहीं करता है ' एक भेजे गए पैकेट (एक टाइमआउट और दो रिट्रीज़ के बाद) को एसीके प्रतिक्रिया प्राप्त नहीं होती है।

एएसओ की असीमित प्रकृति की वजह से, एक सुंदर डिस्कनेक्शन के अधिसूचित होने का सबसे आसान तरीका एक उत्कृष्ट async_read है जो कनेक्शन बंद होने पर तुरंत error::eof लौटाएगा। लेकिन यह अकेले अभी भी अन्य मुद्दों की संभावना छोड़ देता है जैसे अर्ध-खुले कनेक्शन और नेटवर्क मुद्दे ज्ञात नहीं जा रहे हैं।

अप्रत्याशित कनेक्शन बाधा के आसपास काम करने का सबसे प्रभावी तरीका किसी प्रकार के जीवित या पिंग का उपयोग करना है। कनेक्शन पर डेटा स्थानांतरित करने का यह कभी-कभी प्रयास अनजाने में अलग कनेक्शन के त्वरित पहचान की अनुमति देगा।

टीसीपी प्रोटोकॉल में वास्तव में अंतर्निहित keep-alive mechanism है जिसे asio::tcp::socket::keep_alive का उपयोग करके एएसओ में कॉन्फ़िगर किया जा सकता है। टीसीपी को जीवित रखने के बारे में अच्छी बात यह है कि यह उपयोगकर्ता-मोड एप्लिकेशन के लिए पारदर्शी है, और केवल रहने वाले लोगों में दिलचस्पी रखने वाले सहकर्मी इसे कॉन्फ़िगर करते हैं। नकारात्मकता यह है कि आपको टाइमआउट पैरामीटर को कॉन्फ़िगर करने के लिए ओएस लेवल एक्सेस/ज्ञान की आवश्यकता होती है, दुर्भाग्य से वे एक साधारण सॉकेट विकल्प के माध्यम से प्रकट नहीं होते हैं और आमतौर पर डिफ़ॉल्ट टाइमआउट मान होते हैं जो काफी बड़े होते हैं (लिनक्स पर 7200 सेकेंड)।

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

+0

रख-रखाव के साथ एक समस्या है: मेरे पास उन सर्वरों तक पहुंच नहीं है जहां एप्लिकेशन चलाया जाएगा, इसलिए मैं रख-रखाव टाइमआउट (7200 सेकेंड यहां) नहीं बदल सकता। लेकिन मुझे यह प्रतिक्रिया पसंद है, इसलिए यदि मुझे फिर से इसकी ज़रूरत है तो मैं टीसीपी कील-जिंदा सक्षम करूंगा। धन्यवाद – coelhudo

+0

मैं यह कहना भूल गया कि मैंने क्या किया है, मैं बस पढ़ने/लिखने, त्रुटि की जांच करने और इस त्रुटि के आधार पर निर्णय लेने का प्रयास करता हूं। – coelhudo

+0

छवि अब और नहीं दिखाई दे रही है, क्या आप इसे ठीक कर सकते हैं? मैं चित्रण देखना चाहता हूं। धन्यवाद। – coelhudo

0

आप एक सॉकेट पर एक डमी बाइट भेज सकते हैं और देख सकते हैं कि यह एक त्रुटि वापस करेगा या नहीं।

+3

लेकिन अगर आप जुड़े हुए हैं तो यह दूसरी छोर के साथ क्या होता है जब यह डमी बाइट प्राप्त करता है। यह एक अच्छा समाधान नहीं है। – jmucchiello

+2

आमतौर पर इस तरह के आवेदन में समय-समय पर दिल की धड़कन की अवधारणा होती है। इसके अलावा, विंडोज़ (win32) पर कनेक्शन को विश्वसनीय रूप से जांचने का कोई तरीका नहीं है, और boost :: asio :: ip :: tcp :: सॉकेट इसके शीर्ष पर लागू किया जाएगा। @jmucchiello - यदि आपने कभी वितरित सिस्टम पर काम किया है, तो आप जानते होंगे कि कनेक्शन हमेशा दिल की धड़कन के माध्यम से चेक किया जाता है, जो आम तौर पर एक बाइट होता है। उम्मीद है कि यह ओपी मदद करता है। – vehomzzz

+0

एक समस्या है, मुझे सर्वर की ओर से व्यवहार नहीं पता है। जो समाधान मैंने पाया, ऑपरेशन से पहले कॉल कनेक्ट है और त्रुटि स्थिति की जांच करें। – coelhudo

1

टीसीपी विश्वसनीय पट्टियों के लिए देखने के लिए वादा करता है - उचित के रूप में पुनः प्रयास करना - भरोसेमंद कुछ परिभाषा के लिए, आपको विश्वसनीय कनेक्शन प्रदान करने के लिए। बेशक टीसीपी उन मामलों को संभाल नहीं सकता है जहां सर्वर क्रैश हो जाता है, या आपका ईथरनेट केबल गिर जाता है या ऐसा कुछ होता है। इसके अतिरिक्त, यह जानकर कि आपका टीसीपी कनेक्शन ऊपर है, इसका मतलब यह नहीं है कि एक प्रोटोकॉल जो टीसीपी कनेक्शन पर जायेगा तैयार है (उदाहरण के लिए, आपका HTTP वेबसर्वर या आपका एफ़टीपी सर्वर कुछ टूटी हुई स्थिति में हो सकता है)।

यदि आप जानते हैं प्रोटोकॉल टीसीपी पर भेजा जा रहा है तो शायद उस प्रोटोकॉल में एक तरीका है आपको बताने के लिए अगर चीजें (HTTP के लिए यह होगा एक HEAD request)

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