2009-06-09 19 views
22

जब मैं उदा। PUTTY और मेरा कनेक्शन खो जाता है (या जब मैं विंडोज पर मैनुअल ipconfig /release करता हूं), तो यह सीधे प्रतिक्रिया देता है और सूचित करता है कि मेरा कनेक्शन खो गया था।जावा पता खो गया कनेक्शन

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

मैंने Socket.isConnected() विधि का उपयोग करने की कोशिश की लेकिन यह हमेशा के लिए हमेशा "सत्य" वापस आ जाएगा। मैं जावा में यह कैसे कर सकता हूं?

उत्तर

18

अच्छा, यह बताने का सबसे अच्छा तरीका है कि आपका कनेक्शन बाधित है या नहीं, सॉकेट से पढ़ने/लिखने का प्रयास करना है। यदि ऑपरेशन विफल रहता है, तो आप कभी-कभी अपना कनेक्शन खो चुके हैं।

तो, आपको कुछ अंतराल पर पढ़ने का प्रयास करना है, और अगर पढ़ने में विफल रहता है तो पुनः कनेक्ट करने का प्रयास करें।

आपके लिए महत्वपूर्ण घटनाएं तब होती हैं जब एक पठन विफल हो जाता है - आप कनेक्शन खो देते हैं, और जब कोई नई सॉकेट जुड़ी होती है - तो आप कनेक्शन प्राप्त कर लेते हैं।

इस तरह आप समय और समय का ट्रैक रख सकते हैं।

+0

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

+2

@EJP यह हमेशा सही नहीं होता है, लेकिन यह आपको क्या हो रहा है इसके बारे में एक अच्छा विचार देगा। – jjnguy

+11

नहीं, यह नहीं होगा। आप धीमे सर्वर और रीड टाइमआउट के साथ खोए गए कनेक्शन के बीच अंतर नहीं कर सकते हैं। – EJP

7

java.net.InetAddress कक्षा के isReachable() विधि का उपयोग क्यों नहीं करें?

इस कैसे काम करता है JVM कार्यान्वयन विशिष्ट लेकिन है:

एक ठेठ कार्यान्वयन ICMP ECHO अनुरोधों का उपयोग करता है, तो विशेषाधिकार प्राप्त किया जा सकता है, अन्यथा यह की पर बंदरगाह 7 (इको) एक टीसीपी जुड़ाव स्थापित करने की कोशिश करेंगे होगा गंतव्य मेजबान।

आप एक कनेक्शन लगातार खुला रखने के लिए ताकि आप देख सकते हैं जब कि विफल रहता है आप isReachable() होने के बजाय ECHO protocol खुद चल सर्वर से कनेक्ट कर सकता है यह तुम्हारे लिए क्या और पढ़ सकते हैं और डेटा लिखने और इसे विफल के लिए इंतजार करना चाहते हैं ।

+1

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

+0

आप अपने आप को एक ईसीएचओ सर्वर से कनेक्ट कर सकते हैं और डेटा भेजना और पढ़ना जारी रख सकते हैं; इसे उत्तर में जोड़ा गया। –

+0

चाहे कोई मौजूदा कनेक्शन अभी भी खुला है, ''पहुंच योग्य()' के साथ कुछ भी नहीं है। – EJP

0

आप प्रत्येक मशीन को एक मशीन पिंग कर सकते हैं, और यह बहुत सटीक होगा। सावधान रहें कि आप इसे डॉस नहीं करते हैं।

एक और विकल्प रिमोट मशीन पर एक छोटा सर्वर चलाएगा और इसके साथ कनेक्शन बनाएगा।

+0

जब आप छोटे सर्वर से डिस्कनेक्ट हो जाते हैं तो आप कैसे जानेंगे? और जावा का एक ** प्रमुख ** उपयोग एंड्रॉइड मोबाइल उपकरणों में है जहां निरंतर पिंगिंग और रखरखाव एक बुरा विचार है क्योंकि वे बैटरी को मार देते हैं। – user316117

0

याहू/Google या कहीं ऐसा कनेक्ट करने के लिए यह संभवतः आसान है।

URL yahoo = new URL("http://www.yahoo.com/"); 
    URLConnection yc = yahoo.openConnection(); 
    int dataLen = yc.getContentLength() ; 

नील

+0

कोई मौजूदा कनेक्शन अभी भी खुला है या नहीं, इसके साथ कुछ भी नहीं करना है। – EJP

+0

प्रश्न "जावा प्रोग्राम जो मेरे इंटरनेट कनेक्शन पर नज़र रखता है" लिखना था, जो यह ठीक करेगा। यदि पुटी कनेक्शन गुम हो जाता है तो जावा सीधे निगरानी नहीं कर सकता है लेकिन कहेंगे कि एक सामान्य नेटवर्क समस्या कब होती है। आप किसी अन्य प्रक्रिया से नेटवर्क कनेक्शन की निगरानी के लिए जावा से "नेटस्टैट" को कॉल कर सकते हैं। –

+0

WinSock का उपयोग कर विंडोज प्रोग्रामर एक ईवेंट के लिए पंजीकरण कर सकते हैं। एक केबल डिस्कनेक्ट होने के बाद भी यह आग लगती है। (कुछ सेकंड विलंब के साथ) [https://stackoverflow.com/questions/44681648/in-android-how-can-i-receive-an-event-when-my-socket-closes-or-disconnects ](लिंक) – user316117

1

आप सॉकेट timeout interval में देखने का प्रयास कर सकते हैं। एक संक्षिप्त टाइमआउट के साथ (I मानते हैं डिफ़ॉल्ट 'अनंत टाइमआउट' है) तो हो सकता है कि होस्ट अपरिहार्य हो जाने पर आप अपवाद या कुछ फंसाने में सक्षम हो।

+1

यह सभी मामलों का पता नहीं लगाता है। आपको सॉकेट में कुछ पढ़ना या लिखना है। – tputkonen

10

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

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

(*) वहाँ भी एक तंत्र बुलाया टीसीपी keepalive है लेकिन कई ओएस आप सभी अनुप्रयोगों के लिए इसे सक्रिय करने के लिए है में, और यह अगर तुम जल्दी से कनेक्शन के नुकसान की सूचना के लिए

1

ठीक चाहते हैं उपयोग करने के लिए वास्तव में व्यावहारिक नहीं है तो मैं अंत में

try 
{ 
    Socket s = new Socket("stackoverflow.com",80); 
    DataOutputStream os = new DataOutputStream(s.getOutputStream()); 
    DataInputStream is = new DataInputStream(s.getInputStream()); 
    while (true) 
    { 
     os.writeBytes("GET /index.html HTTP/1.0\n\n"); 
     is.available(); 
     Thread.sleep(1000); 
    } 
} 
catch (IOException e) 
{ 
    System.out.println("connection probably lost"); 
    e.printStackTrace(); 
} 

के रूप में साफ नहीं के साथ काम कर के रूप में मैं आशा व्यक्त की समझ में आ गया है, लेकिन यह काम नहीं कर रहा है, तो मैं os.writeBytes बाहर छोड़()।

+17

यह ऐसा कुछ है जिसे आप निश्चित रूप से उपयोग नहीं करना चाहिए। इसे लगभग stackoverflow.com के खिलाफ एक डॉस हमले के रूप में माना जा सकता है! – tputkonen

+0

ऐसा करने का एक और दोस्ताना तरीका वेब होस्ट पर एक साधारण पृष्ठ/स्क्रिप्ट होस्ट करना होगा (संभवतः) इस तरह के निरंतर भार को ध्यान में रखेगा, खासकर यदि प्रस्तुत पृष्ठ छोटा था (केवल एक साधारण "एच" करेगा)। यह एक छोटा सा पैर प्रिंट प्रदान करना चाहिए और यदि कॉल हर सेकेंड में किए जाते हैं या तो सर्वर संभवतः एक डॉस में परिणाम नहीं डालता है। वैसे भी सिद्धांत में। – Kingsolmn

+4

यह बकवास है। कॉलिंग उपलब्ध() आमतौर पर व्यर्थ है, और इसे कॉल कर रहा है और परिणाम को निश्चित रूप से फेंक रहा है। नींद सचमुच समय की बर्बादी है। यह तकनीक ठीक से कुछ भी नहीं करती है। – EJP

4

ग्राहक ठीक से डिस्कनेक्ट है, तो एक read() -1, readLine() रिटर्न अशक्त, readXXX() किसी अन्य एक्स के लिए फेंकता EOFException वापस आ जाएगी। खोए गए टीसीपी कनेक्शन का पता लगाने का एकमात्र विश्वसनीय तरीका इसे लिखना है। आखिरकार IOException 'कनेक्शन रीसेट' फेंक देगा, लेकिन बफरिंग के कारण कम से कम दो लिखते हैं।

1

isConnected() सॉकेट.जावा वर्ग के अंदर विधि थोड़ा भ्रामक है। यह आपको नहीं बताता है कि सॉकेट वर्तमान में रिमोट होस्ट से जुड़ा हुआ है (जैसे कि यह अनजान है)। इसके बजाय, यह आपको बताता है कि सॉकेट को कभी भी रिमोट होस्ट से कनेक्ट किया गया है या नहीं। यदि सॉकेट रिमोट होस्ट से कनेक्ट करने में सक्षम था, तो यह विधि 0 सॉर्ट बंद होने के बाद भी true लौटाती है। यह बताने के लिए कि क्या सॉकेट वर्तमान में खुला है, आपको यह जांचना होगा कि isConnected()true और isClosed() रिटर्न false देता है। उदाहरण के लिए:

boolean connected = socket.isConnected() && !socket.isClosed(); 
+0

_To बताएं कि क्या सॉकेट वर्तमान में खुला है या नहीं, आपको यह जांचना होगा कि कनेक्ट किया गया है() सत्य लौटाता है और isClosed() देता है false_ यह सच नहीं लगता है। देखें: [https://stackoverflow.com/questions/44685374/why-am-i-sending-an-rst-if-my-socket-is-connected-and-not-closed] (लिंक) – user316117

+0

@ user316117 प्रश्न स्पष्ट नहीं है, लेकिन यदि बंद है गलत है और कनेक्ट है तो सत्य है इसका मतलब है कि आप कनेक्ट करने में कामयाब रहे और कनेक्शन कभी बंद नहीं हुआ। अगर आपको लगता है कि आप डिस्कनेक्ट हैं और "isclosed()" FALSE लौटाता है तो आपने एक जेडीके बग खोज ली है। इस दस्तावेज़ को देखें: https://docs.oracle.com/javase/8/docs/api/java/net/Socket.html#is कनेक्टेड - – Alboz

+0

@Alboz इसका मतलब है कि आप कनेक्ट करने में कामयाब रहे हैं और * सॉकेट * नहीं है अभी तक बंद कर दिया गया है। कनेक्शन के साथ इसका कोई लेना-देना नहीं है, जैसा आपने स्वयं अपने उत्तर में कहा था। जब तक आप अपनी सॉकेट बंद नहीं करते हैं तब तक कोई जेडीके बग नहीं होता है और फिर 'isClosed() == false' प्राप्त होता है। – EJP

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