2008-09-15 24 views
80

मुझे सॉकेट से पढ़ने की कोशिश करने में निम्न त्रुटि मिल रही है। मैं readInt() पर InputStream पर कर रहा हूं, और मुझे यह त्रुटि मिल रही है। दस्तावेज़ीकरण को समझने से यह पता चलता है कि कनेक्शन के ग्राहक भाग ने कनेक्शन बंद कर दिया है। इस परिदृश्य में, मैं सर्वर हूं।java.net.SocketException: कनेक्शन रीसेट

मेरे पास क्लाइंट लॉग फ़ाइलों तक पहुंच है और यह कनेक्शन बंद नहीं कर रहा है, और वास्तव में इसकी लॉग फाइलें सुझाव देती हैं कि मैं कनेक्शन बंद कर रहा हूं। तो क्या किसी के पास कोई विचार है कि यह क्यों हो रहा है? और जांचने के लिए और क्या? क्या यह तब उठता है जब स्थानीय संसाधन होते हैं जो शायद सीमा तक पहुंच रहे हैं?


मैं ध्यान दें कि मैं निम्न पंक्ति की क्या ज़रूरत है:

readInt() को
socket.setSoTimeout(10000); 

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

वैसे भी, बस इसका उल्लेख करते हुए, उम्मीद है कि लाल हेरिंग नहीं है। :-(

+0

आप दोनों पक्षों से निशान ढेर है? क्या आप नेटवर्क आर्किटेक्चर का थोड़ा और वर्णन कर सकते हैं? (जंगली इंटरनेट पर? एक ही मशीन पर? कहीं बीच में?) क्या यह हर समय होता है? या अंतःस्थापित? –

उत्तर

8

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

31

कनेक्शन बस रीसेट मतलब है कि एक टीसीपी आरएसटी प्राप्त किया गया था। यह तब होता है जब आपके सहकर्मी डेटा है कि यह प्रक्रिया नहीं कर सकते प्राप्त करता है, और वहाँ उस के लिए विभिन्न कारणों से हो सकता है।

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

अन्य मामलों में, एक हस्तक्षेप फ़ायरवॉल या यहां तक ​​कि रिमोट होस्ट स्वयं भी आपके टीसीपी कनेक्शन के बारे में "भूल" सकता है। ऐसा तब हो सकता है जब आप लंबे समय तक कोई डेटा नहीं भेजते (2 घंटे एक आम टाइम-आउट होता है), या क्योंकि सहकर्मी को रिबूट किया गया था और सक्रिय कनेक्शन के बारे में इसकी जानकारी खो दी गई थी। इन निष्क्रिय कनेक्शनों में से किसी एक पर डेटा भेजना आरएसटी भी पैदा करेगा।

में अतिरिक्त जानकारी के जवाब में

अद्यतन:

SocketTimeoutException के अपने को संभालने पर एक करीबी नजर डालें। सॉकेट ऑपरेशन पर अवरुद्ध होने पर कॉन्फ़िगर किया गया टाइमआउट पार हो जाने पर यह अपवाद उठाया जाता है। जब यह अपवाद फेंक दिया जाता है तो सॉकेट की स्थिति स्वयं नहीं बदली जाती है, लेकिन यदि आपका अपवाद हैंडलर सॉकेट बंद कर देता है, और फिर इसे लिखने का प्रयास करता है, तो आप एक कनेक्शन रीसेट स्थिति में होंगे। setSoTimeout() आपको read() ऑपरेशन को तोड़ने का एक साफ तरीका देने के लिए है जो अन्यथा थ्रेड चीजों को बिना किसी धागे से बंद करने जैसी गंदे चीजों के बिना, हमेशा के लिए अवरुद्ध कर सकता है।

+0

कई मामलों में सही नहीं है। कचरा संग्रह और प्रक्रिया दोनों उचित बंद होने का कारण बनती है, रीसेट नहीं करती है, लेकिन सहकर्मी द्वारा लिखे गए एक करीबी के बाद एक ईओएस की बजाय रीसेट प्रेरित कर सकते हैं। सॉकेटटाइमआउट अपवाद केवल तभी उठाए जाते हैं जब पाठक ने रीड टाइमआउट सेट किया हो। – EJP

+0

और इसका मतलब यह नहीं है कि एक आरएसटी प्राप्त हुआ था। इसका मतलब यह भी हो सकता है कि इस तरफ से उत्पन्न किया गया था। – EJP

+3

ईजेपी अभी भी 5 साल बाद नमकीन है? – Daedric

81

कई संभावित कारण हैं।

  1. दूसरे छोर ने जानबूझकर कनेक्शन को रीसेट कर दिया है, जिस तरह से मैं यहां दस्तावेज नहीं करूंगा। ऐसा करने के लिए एप्लिकेशन सॉफ़्टवेयर के लिए यह दुर्लभ है, और आम तौर पर गलत है, लेकिन यह वाणिज्यिक सॉफ्टवेयर के लिए अज्ञात नहीं है।

  2. अधिकतर, यह एक कनेक्शन को लिखकर होता है जो दूसरे छोर को सामान्य रूप से बंद कर दिया जाता है। दूसरे शब्दों में एक अनुप्रयोग प्रोटोकॉल त्रुटि।

  3. सॉकेट प्राप्त बफर में अपठित डेटा होने पर यह सॉकेट बंद करके भी हो सकता है।

  4. विंडोज़ में, 'सॉफ़्टवेयर कनेक्शन अपरोर्ट' होता है, जो 'कनेक्शन रीसेट' जैसा नहीं है, आपके अंत से भेजने वाली नेटवर्क समस्याओं के कारण होता है। इसके बारे में एक माइक्रोसॉफ्ट ज्ञान आधार आलेख है।

+1

FYI http://support.microsoft.com/kb/204594 –

+0

@MattLyons धन्यवाद। उससे बेहतर एमएसडीएन लेख हैं। सचमुच मुझे लगता है कि विश्वास करना मुश्किल है। एक कनेक्शन तब तक अस्तित्व में नहीं रहेगा जब तक सही स्रोत और लक्ष्य आईपी पते स्थापित नहीं किए जाते। मैंने देखा है कि एमएसडीएन लेख कनेक्शन के समय लगातार नेटवर्क त्रुटियों का संदर्भ लें। – EJP

3

मुझे एक ही त्रुटि थी। मुझे अब समस्या का समाधान मिला। समस्या स्ट्रीम सर्वर पढ़ने से पहले क्लाइंट प्रोग्राम खत्म हो रहा था।

+0

इससे इस अपवाद का कारण नहीं होगा। – EJP

+0

यह होगा अगर System.exit (0) प्रोग्राम को मारता है और कोई भी socket.close() को कॉल नहीं करता है क्योंकि कनेक्शन खराब स्थिति में है और ठीक से बंद नहीं किया गया था। बहुत अच्छी तरह से कहा गया कि उसके पास एक क्लाइंट प्रोग्राम था जो सॉकेट बंद किए बिना बंद हो गया था;) जो एक बुरी चीज है और इसे ठीक किया जाना चाहिए। –

+0

@DeanHiller नहीं यह नहीं होगा। ऑपरेटिंग सिस्टम सॉकेट को उसी तरह से बंद कर देगा जैसा एप्लिकेशन होना चाहिए। – EJP

5

यह कहने के लिए शर्मनाक है, लेकिन जब मुझे यह समस्या थी, तो यह केवल एक गलती थी कि मैं सभी डेटा पढ़ने से पहले कनेक्शन बंद कर रहा था। छोटे तारों को वापस करने के मामले में, यह काम करता था, लेकिन शायद इसे बंद करने से पहले, पूरी प्रतिक्रिया के कारण यह बफर किया गया था।

लंबे समय तक पाठ लौटने के मामलों में, अपवाद फेंक दिया गया था, क्योंकि अधिकतर एक बफर वापस आ रहा था।

आप इस निरीक्षण की जांच कर सकते हैं। याद रखें कि एक यूआरएल खोलना एक फ़ाइल की तरह है, इसे पूरी तरह से पढ़ने के बाद इसे बंद करना (कनेक्शन जारी करना) सुनिश्चित करें।

1

मुझे जावा प्रोग्राम के साथ एसएसएच के माध्यम से सर्वर पर कमांड भेजने की कोशिश करने में यह समस्या भी थी। समस्या जावा कोड निष्पादित मशीन के साथ थी। रिमोट सर्वर से कनेक्ट करने की अनुमति नहीं थी। लिखना() विधि ठीक से कर रही थी, लेकिन पढ़ने() विधि java.net फेंक रही थी। सॉकेट अपवाद: कनेक्शन रीसेट। मैंने रिमोट सर्वर ज्ञात कुंजी पर क्लाइंट एसएसएच कुंजी जोड़ने के साथ इस समस्या को ठीक किया है।

2

मुझे जावा में लिखी गई एसओए प्रणाली के साथ यह समस्या थी। मैं क्लाइंट और सर्वर दोनों को विभिन्न भौतिक मशीनों पर चला रहा था और उन्होंने लंबे समय तक ठीक काम किया, फिर उन ग़लत कनेक्शन रीसेट क्लाइंट लॉग में दिखाई दिए और सर्वर लॉग में कुछ भी अजीब नहीं था। क्लाइंट और सर्वर दोनों को पुनरारंभ करने से समस्या हल नहीं हुई। अंत में हमने पाया कि सर्वर की तरफ ढेर इतना भरा था इसलिए हमने जेवीएम में उपलब्ध स्मृति में वृद्धि की: समस्या हल हो गई! ध्यान दें कि लॉग में कोई आउटऑफमेरी एरर नहीं था: स्मृति केवल दुर्लभ थी, थक नहीं गई थी।

5

पूर्ण बहुत सावधानी से ट्रेस का निरीक्षण करना चाहिए,

मैं एक सर्वर सॉकेट आवेदन किया है और एक java.net.SocketException: Connection reset मामले तय की।

मेरे मामले में यह क्लाइंट सॉकेट Socket ऑब्जेक्ट से पढ़ने के दौरान होता है जो किसी कारण से कनेक्शन बंद कर देता है। (नेटवर्क खो गया, फ़ायरवॉल या एप्लिकेशन क्रैश या इच्छित बंद)

वास्तव में जब मैं इस सॉकेट ऑब्जेक्ट से पढ़ने में त्रुटि प्राप्त करता था तो मैं कनेक्शन को फिर से स्थापित कर रहा था।

Socket clientSocket = ServerSocket.accept(); 
is = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); 
int readed = is.read(); // WHERE ERROR STARTS !!! 

दिलचस्प बात यह है for my JAVA Socket यदि एक ग्राहक मेरे ServerSocket को जोड़ता है और जबकि इस सॉकेट से पढ़ने के लिए पाश recursively.It क्योंकि एक अनंत में होने का लगता है कुछ भी is.read() ही कॉल भेजने के बिना अपने कनेक्शन बंद आप पढ़ने की कोशिश है एक बंद कनेक्शन से। यदि आप पढ़ने के लिए नीचे कुछ ऐसा उपयोग करते हैं;

while(true) 
{ 
    Receive(); 
} 

तो फिर तुम पर नीचे की तरह और

java.net.SocketException: Socket is closed 
    at java.net.ServerSocket.accept(ServerSocket.java:494) 

मैं क्या सिर्फ ServerSocket बंद करने और मेरे कनेक्शन के नवीनीकरण और आगे आने वाली ग्राहक कनेक्शन

String Receive() throws Exception 
{ 
try {     
      int readed = is.read(); 
      .... 
}catch(Exception e) 
{ 
     tryReConnect(); 
     logit(); //etc 
} 


//... 
} 

के लिए इंतज़ार कर रहा है पर एक स्टैकट्रेस कुछ पाने यह अज्ञात क्लाइंट सॉकेट के लिए मेरा कनेक्शन पुनः स्थापित करता है

private void tryReConnect() 
     { 
      try 
      { 
       ServerSocket.close(); 
       //empty my old lost connection and let it get by garbage col. immediately 
       clientSocket=null; 
       System.gc(); 
       //Wait a new client Socket connection and address this to my local variable 
       clientSocket= ServerSocket.accept(); // Waiting for another Connection 
       System.out.println("Connection established..."); 
      }catch (Exception e) { 
       String message="ReConnect not successful "+e.getMessage(); 
       logit();//etc... 
      } 
     } 

मुझे एक और तरीका नहीं मिला क्योंकि जैसा कि आप नीचे की छवि से देखते हैं, आप समझ नहीं सकते हैं कि try and catch के बिना कनेक्शन खो गया है या नहीं, क्योंकि सब ठीक लगता है। मुझे यह स्नैपशॉट मिला जबकि मुझे लगातार Connection reset मिल रहा था।

enter image description here

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