2009-05-04 12 views
5

कनेक्शन के रिमोट साइड पर सॉकेट बंद होने की जांच करने का सबसे आसान तरीका क्या है? socket::is_open() रिमोट साइड पर बंद होने पर भी सत्य लौटाता है (मैं boost::asio::ip::tcp::socket का उपयोग कर रहा हूं)।Boost.Asio में सॉकेट बंद होने पर कैसे जांचें?

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

+0

रिमोट कनेक्शन बंद होने पर आपको यह जानने की आवश्यकता क्यों है? – outis

+0

इसके अलावा, क्या आप अपने स्वयं के डिज़ाइन या मानक प्रोटोकॉल के अनुप्रयोग प्रोटोकॉल का उपयोग कर रहे हैं? – outis

+0

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

उत्तर

4

यदि कनेक्शन को पीयर द्वारा साफ रूप से बंद कर दिया गया है तो आपको पढ़ने के दौरान एक ईओएफ प्राप्त करना चाहिए। अन्यथा मैं यह पता लगाने के लिए आम तौर पर पिंग करता हूं कि कनेक्शन वास्तव में जिंदा है या नहीं।

+1

... और मुझे ईओएफ प्राप्त करने के लिए पढ़ने की जरूरत है। मुझे लगता है कि उसके आस-पास कोई रास्ता नहीं है। धन्यवाद! – Hali

7

क्या कोई बढ़ावा देने वाला फ़ंक्शन उपलब्ध है? अधिकांश सॉकेट कार्यान्वयन के पास कतार से इसे हटाए बिना डेटा पढ़ने का एक तरीका होता है, ताकि आप इसे बाद में पढ़ सकें। यह आपकी आवश्यकताओं को पूरा करने के लिए प्रतीत होता है।

तेजी से एएसओ दस्तावेज़ों के माध्यम से चमकने के बाद, मैं बिल्कुल वही नहीं ढूंढ पाया जो मैं उम्मीद कर रहा था, लेकिन इसका मतलब यह नहीं है कि इसका वहां नहीं है।

मैं स्टार्टर्स के लिए this का सुझाव दूंगा।

+0

हाँ, आप सही हैं। आप "प्राप्त" विधि में ध्वज पास कर सकते हैं जो बताता है कि यह डेटा को नहीं हटाता है। मैं "read_some" विधि का उपयोग कर रहा था, जिसमें यह ध्वज तर्क नहीं है। इस पर ध्यान दिलाने के लिए धन्यवाद! – Hali

+0

मान लीजिए कि आपने सॉकेट और प्रतिक्रिया सेट की है तो आप एक स्ट्रीम सेट कर सकते हैं उदा। std :: istream myhttpstream (और presponse); और फिर आप std :: istream :: peek() फ़ंक्शन का उपयोग कर सकते हैं। –

+0

मैं यह करता हूं: प्राप्त = सॉकेट() प्राप्त करें (boost :: asio :: buffer (buf), tcp :: सॉकेट :: message_peek); –

1

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

0

त्रुटि_code का उपयोग कर स्थिति को जांचने में सक्षम है कि क्लाइंट कनेक्ट है या नहीं। यदि कनेक्शन सफलता है, तो त्रुटि_code error.value() 0 लौटाएगा, अन्यथा अन्य मान वापस कर देगा। आप error_code से संदेश() भी देख सकते हैं।

7

बस अपने async_receive हैंडलर में boost::asio::error::eof त्रुटि की जांच करें। इसका मतलब है कि कनेक्शन बंद कर दिया गया है। ऐसा करने का यही एकमात्र उचित तरीका है।

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