java.net.SocketException: कनेक्शन रीसेट


128

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

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


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

socket.setSoTimeout(10000);

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

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


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

जवाबों:


116

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

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

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

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

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


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

48

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

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

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


अतिरिक्त जानकारी के जवाब में अपडेट करें:

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


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

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

17

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


9

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

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

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


9

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

मेरे पास एक सर्वर सॉकेट एप्लिकेशन है और एक 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पास कनेक्ट करता है और अपने कनेक्शन को बिना 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लगातार मिलने के दौरान मुझे यह स्नैपशॉट मिला ।

यहाँ छवि विवरण दर्ज करें


6

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


इससे यह अपवाद नहीं होगा।
लोर्न

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

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

@ ईजेपी .... मुझे यकीन नहीं है ... मुझे पता है कि हम इसे System.exit के साथ पुन: पेश कर सकते हैं, लेकिन मुझे OS / config याद नहीं है क्योंकि यह कुछ समय पहले था .... सॉकेट कॉलिंग ( ) सर्वर पर कनेक्शन रीसेट को रोका गया और इसने अधिक उचित व्यवहार किया।
डीन हिलर

2
@DeanHiller लेखन प्रक्रिया से पहले पढ़ने की प्रक्रिया समाप्त हो गई थी।
लोर्ने का मार्कीस

4

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


2

अपने सर्वर के जावा संस्करण की जाँच करें। मेरे पास आया क्योंकि मेरा वेबलॉग 10.3.6 JDK 1.7.0_75 पर था जो TLSv1 पर था। बाकी समाप्ति बिंदु जो मैं उपभोग करने की कोशिश कर रहा था, वह TLSv1.2 से नीचे कुछ भी बंद कर रहा था।

डिफ़ॉल्ट रूप से वेबलॉजिक सबसे मजबूत साझा प्रोटोकॉल पर बातचीत करने की कोशिश कर रहा था। यहां देखें विवरण: HTTPS कनेक्शन के लिए https.protocols सिस्टम प्रॉपर्टी सेट करने के मुद्दे

मैंने समर्थित TLS की पहचान करने के लिए वर्बोज़ SSL लॉगिंग को जोड़ा। यह संकेत दिया गया कि TLSv1 का इस्तेमाल हैंडशेक के लिए किया जा रहा है।
-Djavax.net.debug=ssl:handshake:verbose:keymanager:trustmanager -Djava.security.debug=access:stack

मैंने इस फीचर को हमारे JDK8- संगत उत्पाद, JDK8 चूक से TLSv1.2 में धकेल दिया। JDK7 तक सीमित रहने वालों के लिए, मैंने भी TLSv1.2 में अपग्रेड करके Java 7 के लिए वर्कअराउंड का सफलतापूर्वक परीक्षण किया। मैंने इस उत्तर का उपयोग किया: जावा 7 में टीएलएस 1.2 को कैसे सक्षम किया जाए


बहुत धन्यवाद, आपने मुझे अपना मुद्दा ठीक करने के लिए एक नई दिशा दिखाई। और अंत में मैंने पाया कि यह मामला है !!!
कार्ल ली

1

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


0

मेरे अनुभव में, मैं अक्सर निम्नलिखित स्थितियों का सामना करता हूं;

  1. यदि आप एक कॉर्पोरेट कंपनी में काम करते हैं, तो नेटवर्क और सुरक्षा टीम से संपर्क करें। क्योंकि बाहरी सेवाओं के लिए किए गए अनुरोधों में, प्रासंगिक समापन बिंदु के लिए अनुमति देना आवश्यक हो सकता है

  2. एक और मुद्दा यह है कि एसएसएल सर्टिफिकेट उस सर्वर पर समाप्त हो सकता है जहां आपका एप्लिकेशन चल रहा है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.