2010-06-29 7 views
7

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

प्रलेखन के अनुसार जावा सॉकेट को अपवाद फेंकना चाहिए यदि आप किसी सॉकेट को लिखने का प्रयास करते हैं जो दूसरे छोर पर पहुंच योग्य नहीं है!

उत्तर

0

टीसीपी/आईपी संचार बहुत अजीब हो सकता है। टीसीपी कभी भी ऊपरी परतों को बताने के बिना ढेर के नीचे परतों पर थोड़ी देर के लिए पुनः प्रयास करेगा, कुछ भी हुआ।

मैं पूरी तरह से उम्मीद होती है कि कुछ समय अवधि के बाद (कुछ ही मिनटों के लिए 30 सेकंड) आपको एक त्रुटि दिखाई चाहिए, लेकिन मैं इस परीक्षण नहीं किया मैं बस कैसे टीसीपी क्षुधा काम करते हैं बंद जा रहा हूँ।

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

इसके अलावा, यह हो सकता है कि मैं पूरी तरह से गलत हूं और जावा का कार्यान्वयन जो आप उपयोग कर रहे हैं वह केवल flaky है।

2

अंततः रिट्रांसमिट टाइमआउट (आरटीओ) द्वारा कनेक्शन का समय समाप्त हो जाएगा। हालांकि, आरटीओ एक जटिल नेटवर्क विलंबता (RTT) के आधार पर एल्गोरिथ्म का उपयोग कर गणना की जाती है, इस RFC देखें,

http://www.ietf.org/rfc/rfc2988.txt

तो मोबाइल नेटवर्क पर, इस मिनट हो सकता है। यह देखने के लिए कि क्या आप टाइमआउट प्राप्त कर सकते हैं, 10 मिनट प्रतीक्षा करें।

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

1

यहां कुंजी शब्द (without closing the socket properly) है।

सॉकेट हमेशा हासिल कर ली जानी चाहिए और का निपटारा इस तरह से:

final Socket socket = ...; // connect code 

try 
{ 
    use(socket); // use socket 
} 
finally 
{ 
    socket.close(); // dispose 
} 
यहां तक ​​कि इस सावधानियों आप आवेदन की समय समाप्ति, अपने प्रोटोकॉल के लिए विशिष्ट निर्दिष्ट करना चाहिए साथ

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

है यही कारण है कि आप एक निगरानी धागा है कि आपके आवेदन समय समाप्ति को लागू करता है सॉकेट कि थोड़ी देर के लिए उत्तर नहीं दे रहा है की disposes की जरूरत है।

ऐसा करने का एक सुविधाजनक तरीका जावा.एनओ में संबंधित चैनलों के माध्यम से सॉकेट और सर्वर सॉकेट को प्रारंभ करना है। ऐसे सॉकेट का मुख्य लाभ यह है कि वे इंटरप्टिबल हैं, इस तरह आप आसानी से थ्रेड को बाधित कर सकते हैं जो सॉकेट प्रोटोकॉल करता है और सुनिश्चित करें कि सॉकेट ठीक से डिस्पोजेड हो गया है।

सूचना है कि आप दोनों पक्षों पर आवेदन समय समाप्ति को लागू करना चाहिए, के रूप में यह समय और दुर्भाग्य से जब आप अनुत्तरदायी सॉकेट अनुभव हो सकता है का केवल एक मामला है।

0

प्रश्न के पहले भाग का जवाब देने के लिए (क्लाइंट ने अचानक डिस्कनेक्ट नहीं किया है), टीसीपी में, आप यह नहीं जान सकते कि कनेक्शन का उपयोग करने का प्रयास होने तक कनेक्शन समाप्त हो गया है या नहीं।

guaranteed delivery in TCP की धारणा काफी सूक्ष्म है: डिलीवरी वास्तव में दूसरे छोर पर आवेदन की गारंटी नहीं है (यह वास्तव में गारंटीकृत साधनों पर निर्भर करता है)। Section 2.6 of RFC 793 (TCP) इस विषय पर अधिक जानकारी देता है। This thread on the Restlet-discuss list और this thread on the Linux kernel list भी रुचि का हो सकता है।

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

+0

मैंने पहले ही सॉकेट को लिखकर इसका उपयोग करने की कोशिश की है और फिर भी मुझे नहीं पता कि क्लाइंट डिस्कनेक्ट हो गया है या नहीं। – erotsppa

0

मुझे एक ही समस्या का सामना करना पड़ रहा है। मुझे लगता है कि जब आप किसी चयनकर्ता के साथ सॉकेट पंजीकृत करते हैं तो यह कोई अपवाद नहीं फेंकता है। क्या आप अपनी सॉकेट के साथ चयनकर्ता का उपयोग कर रहे हैं?