2009-07-25 12 views
61

मेरे कुछ जावा एनआईओ कनेक्शन के लिए, जब मेरे पास SocketChannel.write(ByteBuffer) कॉल है, तो यह IOException फेंकता है: "टूटा हुआ पाइप"।जावा एनआईओ: IOException क्या करता है: टूटा हुआ पाइप मतलब है?

"टूटी हुई पाइप" का क्या कारण बनता है, और, सबसे महत्वपूर्ण बात यह है कि क्या उस राज्य से पुनर्प्राप्त करना संभव है? यदि इसे पुनर्प्राप्त नहीं किया जा सकता है, तो ऐसा लगता है कि यह एक अच्छा संकेत होगा कि एक अपरिवर्तनीय समस्या आई है और मुझे बस इस सॉकेट कनेक्शन को बंद करना चाहिए। क्या यह एक उचित धारणा है? क्या ऐसा कोई समय है जब यह IOException होगा, जबकि सॉकेट कनेक्शन अभी भी पहले स्थान पर ठीक से जुड़ा हुआ है (किसी बिंदु पर असफल काम करने वाले कनेक्शन के बजाय)?

एक तरफ ध्यान दें पर, यह हमेशा एक SocketChannel.write() प्रयास करने से पहले SocketChannel.isConnected() कॉल करने के लिए, और यदि हां, मैं भी मान सकते हैं कि कनेक्शन "टूटा" है और बंद किया जाना चाहिए अगर दोनों SocketChannel.isConnected() और SocketChannel.isConnectionPending() दोनों false हैं बुद्धिमान है?

धन्यवाद!

उत्तर

18

टूटा हुआ पाइप बस इसका मतलब है कि कनेक्शन विफल हो गया है। यह मानना ​​उचित है कि यह अप्राप्य है, और फिर किसी भी आवश्यक सफाई कार्य (समापन कनेक्शन, आदि) करने के लिए। मुझे विश्वास नहीं है कि आप इसे अभी भी कनेक्शन के कारण कभी नहीं देख पाएंगे।

यदि आप गैर-अवरोधन मोड का उपयोग कर रहे हैं तो सॉकेटChannel.connect विधि झूठी वापसी होगी, और कनेक्शन को पूरा करने के लिए आपको कनेक्शन कनेक्शन और समापन कनेक्ट तरीकों का उपयोग करने की आवश्यकता होगी। मैं आम तौर पर अपेक्षा करता हूं कि चीजें काम करेगी, और फिर विफलता का पता लगाने के लिए अपवादों को पकड़ें, बजाय "कनेक्ट कनेक्ट" पर लगातार कॉल पर निर्भर रहने के बजाय।

+0

आप बिना किसी पाइप के टूटी हुई पाइप नहीं प्राप्त कर सकते हैं। कनेक्शन के पहले आपको असफल कनेक्शन नहीं मिल सकता है। इस उत्तर का अंतिम अनुच्छेद सही लेकिन अप्रासंगिक है। – EJP

1

आपको यह मानना ​​चाहिए कि सॉकेट दूसरे छोर पर बंद था। IOException के लिए एक कोशिश पकड़ ब्लॉक के साथ अपने कोड लपेटें।

आप सॉकेटChannel कनेक्ट है या नहीं, यह निर्धारित करने के लिए आप कनेक्ट कनेक्ट() का उपयोग कर सकते हैं, लेकिन यह आपके लेखन() आमंत्रण समाप्त होने से पहले बदल सकता है। यह देखने के लिए कि क्या आप वास्तव में IOException प्राप्त कर रहे हैं, यह देखने के लिए इसे अपने कैच ब्लॉक में कॉल करने का प्रयास करें।

+4

इस तरह के अपवाद पर, कनेक्ट किया गया है() सच है इससे कोई फर्क नहीं पड़ता कि क्या। इसे पढ़ें "सॉकेट को अतीत में किसी बिंदु पर कनेक्ट किया गया था" – kellogs

+3

इस उत्तर का अंतिम अनुच्छेद पूरी तरह से गलत है। कनेक्ट किया गया है() इस स्थिति का पता नहीं लगाता है। – EJP

73

"टूटी हुई पाइप" का कारण क्या है, और सबसे महत्वपूर्ण बात यह है कि क्या उस राज्य से पुनर्प्राप्त करना संभव है?

यह कनेक्शन को बंद करने के कारण होता है। (यह आपका एप्लिकेशन नहीं है जो कनेक्शन बंद कर देता है: जिसके परिणामस्वरूप एक अलग अपवाद होगा।)

कनेक्शन पुनर्प्राप्त करना संभव नहीं है। आपको एक नया खोलने की जरूरत है।

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

हां। एक बार आपको यह अपवाद प्राप्त हो जाने के बाद, सॉकेट कभी भी काम नहीं करेगा। इसे बंद करना ही एकमात्र समझदार चीज है।

वहाँ कभी एक समय था जब इस IOException जबकि गर्तिका कनेक्शन अभी भी ठीक से पहली जगह (बजाय एक कार्यरत कनेक्शन है कि कुछ बिंदु पर विफल) में जोड़ा जा रहा है घटित होता है?

संख्या (या कम से कम, OS'es नेटवर्क स्टैक, JVM और/या आपके आवेदन की उचित व्यवहार को नष्ट बिना नहीं।)


है यह बुद्धिमान हमेशा कॉल करने के लिए SocketChannel.isConnected() से पहले एक SocketChannel.write() ...

सामान्य में प्रयास कर रहा है, यह एक बुरा विचार कुछ कॉल (बाहरी) संसाधन का उपयोग करता है से पहले r.isXYZ() कॉल करने के लिए है r। एक छोटा सा मौका है कि संसाधन की स्थिति को दो कॉलों के के बीच बदल जाएगी। कार्रवाई करने का एक बेहतर विचार है, असफल कार्रवाई के परिणामस्वरूप IOException (या जो कुछ भी) पकड़ें और जो भी उपचारात्मक कार्रवाई की आवश्यकता हो।

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

15

टूटा हुआ पाइप का मतलब है कि आपने किसी कनेक्शन को लिखा है जो पहले से ही दूसरे छोर से बंद है।

isConnected() इस स्थिति का पता नहीं लगाता है। केवल एक लेखन करता है।

यह बुद्धिमान हमेशा एक SocketChannel.write (प्रयास करने से पहले SocketChannel.isConnected() कॉल करने के लिए)

यह व्यर्थ है। सॉकेट स्वयं कनेक्ट है। आपने इसे जोड़ा कनेक्ट नहीं हो सकता कनेक्शन ही है, और आप इसे केवल कोशिश करके ही निर्धारित कर सकते हैं।

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