2010-03-31 13 views
16

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

 Socket serverSocket = null; 
     TcpListener listener = new TcpListener(1530); 
     listener.Start(); 
     listener.BeginAcceptSocket(new AsyncCallback(delegate(IAsyncResult result) 
     { 
      Debug.WriteLine("ACCEPTING SOCKET CONNECTION"); 
      TcpListener currentListener = (TcpListener)result.AsyncState; 
      serverSocket = currentListener.EndAcceptSocket(result); 
     }), listener); 


     Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
     Debug.WriteLine("client socket connected: " + clientSocket.Connected);//should be FALSE, and it is 
     clientSocket.Connect("localhost", 1530); 
     Debug.WriteLine("client socket connected: " + clientSocket.Connected);//should be TRUE, and it is 

     Thread.Sleep(1000); 
     serverSocket.Close();//closing the server socket here 
     Thread.Sleep(1000); 

     clientSocket.Send(new byte[0]);//sending data should cause the socket to update its Connected property. 
     Debug.WriteLine("client socket connected: " + clientSocket.Connected);//should be FALSE, but its always TRUE 
+0

आगे चर्चा के लिए http://stackoverflow.com/questions/722240/instantly-detect-client-disconnection-from-server-socket देखें। – EricLaw

उत्तर

0

क्या क्लाइंट सॉकेट.एंड() विधि पैकेट के लिए या तो अक्क/नाक के लिए प्रतीक्षा करती है?

यदि आपका कोड अगली पंक्ति पर उड़ रहा है, तो सॉकेट अभी भी यह पता लगाने की कोशिश कर रहा है कि क्या हो रहा है।

+0

आप थ्रेड डाल सकते हैं। भेजने के बाद सो जाओ। इससे कोई फर्क नहीं पड़ता कि आप क्लाइंट सॉकेट कितनी देर तक प्रतीक्षा करते हैं। कनेक्ट किया गया सच रहता है। – BowserKingKoopa

9

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

हालांकि, यहां एक विधि है कि काम करता है:

!(socket.Poll(0, SelectMode.SelectRead) && socket.Available == 0) 

ऐसा नहीं है कि तथ्य यह है कि एक बंद कनेक्शन के रूप में पठनीय भले ही कोई डेटा उपलब्ध है चिह्नित किया जाएगा पर निर्भर करता है।

यदि आप टूटे हुए नेटवर्क केबल्स या कंप्यूटर जैसे परिस्थितियों का पता लगाना चाहते हैं तो अचानक स्थिति बंद हो जाती है, स्थिति थोड़ी अधिक जटिल होती है। उन परिस्थितियों में, आपके कंप्यूटर को कभी भी एक पैकेट प्राप्त नहीं होता है जो दर्शाता है कि सॉकेट बंद हो गया है। इसे पता लगाने की जरूरत है कि रिमोट साइड पैकेट भेजकर गायब हो गया है और यह देखते हुए कि कोई प्रतिक्रिया वापस नहीं आती है। आप इसे अपने प्रोटोकॉल के हिस्से के रूप में एप्लिकेशन स्तर पर कर सकते हैं, या आप टीसीपी KeepAlive विकल्प का उपयोग कर सकते हैं। .NET से TCP Keep Alive का उपयोग करना विशेष रूप से आसान नहीं है; आप अपने प्रोटोकॉल में रख-रखाव तंत्र को बनाने से शायद बेहतर हो सकते हैं (वैकल्पिक रूप से, आप एक अलग प्रश्न पूछ सकते हैं "मैं टीईसी को .NET में जीवित कैसे सक्षम करूं और जीवित अंतराल को कैसे स्थापित करूं?")।

+0

सॉकेट। रोल (0, SelectMode.SelectRead) सर्वर साइड कनेक्शन बंद होने के बाद भी हमेशा मेरे लिए सच हो जाता है। – BowserKingKoopa

+0

इसके अलावा एमएसडीएन दस्तावेज़ कहते हैं कि पोल विधि कुछ स्थितियों का पता नहीं लगा सकती है "जैसे टूटी हुई नेटवर्क केबल, या रिमोट होस्ट को अनजाने में बंद कर दिया गया था"। मैं सिर्फ यह जानना चाहता हूं कि सर्वर साइड सॉकेट है या नहीं, मुझे परवाह नहीं है कि यह क्यों नहीं है। – BowserKingKoopa

+0

@ ब्रोसरकिंगकुओपा: अरे! मूल रूप से पोस्ट किया गया कोड परीक्षण करता है कि सॉकेट * डिस्कनेक्ट * है। मैंने इसे ठीक कर दिया है। जब रिमोट साइड डिस्कनेक्ट हो जाता है, तो पोल() सच हो जाएगा लेकिन सॉकेट होगा। उपलब्ध होगा 0. मैंने टूटे हुए नेटवर्क केबल्स को संभालने के बारे में एक पैराग्राफ भी जोड़ा। –

3

शायद समाधान इसके माध्यम से कुछ डमी डेटा भेजना है और जांचें कि क्या यह समय समाप्त हो गया है?

2

मैं उच्च स्तरीय भाषा सामग्री को अलग करने की सलाह देता हूं और निम्न स्तर के आईओ पर क्या होता है इसका पता लगाने की सलाह देता हूं।

सबसे कम मैंने खोजा है जबकि लिखने के दौरान isectd (Sourceforge पर खोजें)। चयन() सिस्टम कॉल का उपयोग करके, एक बंद सॉकेट के लिए एक वर्णक पठन तैयार हो जाता है, और जब isectd recv() सॉकेट की डिस्कनेक्ट की गई स्थिति की पुष्टि कर सकती है।

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

पीएस। मैंने उपरोक्त सभी को यूआरएल प्रदान किया होगा लेकिन मेरी प्रतिष्ठा (1) इसे अनुमति नहीं देती है।

4

बस अपनी सॉकेट को सामान्य के रूप में लिखें। आपको पता चलेगा कि यह अपवाद से डिस्कनेक्ट होने पर कहता है कि आपका डेटा डिलीवर नहीं किया जा सका।

यदि आपके पास लिखने के लिए कुछ भी नहीं है ... तो कौन परवाह करता है कि यह डिस्कनेक्ट हो गया है? इसे अब डिस्कनेक्ट किया जा सकता है, लेकिन इसकी आवश्यकता होने से पहले वापस आएं - इसे क्यों फाड़ना परेशान करते हैं, और फिर लिंक की मरम्मत होने तक पुनः कनेक्ट होने पर लूपिंग ...खासकर जब आपके पास कुछ भी कहना नहीं था?

यदि यह आपको परेशान करता है, तो अपने प्रोटोकॉल में जीवित रहने को लागू करें। तो आपके पास हर 30 सेकंड या उससे कुछ कहने के लिए कुछ होगा।

+0

+1 अगर सर्वर ने सभी डेटा भेजा है और यह ज़िंदा नहीं है तो इसे सॉकेट बंद करना चाहिए और क्लाइंट को इसे संभालना चाहिए। क्लाइंट के पक्ष से यदि उसे सभी डेटा प्राप्त हुआ तो यह कनेक्शन को बंद कर देता है, सर्वर इसे संभाल लेगा। आपको बस एसईसीसेव/एस पर अपवाद प्राप्त करना चाहिए। किसी को डिस्कनेक्ट होने पर पता होना चाहिए, पोल डिस्कनेक्ट किए गए सॉकेट पर अपवाद भी फेंक देगा – hoodoos

+0

सॉकेट दोनों तरीकों से काम करते हैं, मुख्य मुद्दा तब होता है जब आप सॉकेट का उपयोग करके पुश का उपयोग करते हैं लेकिन सॉकेट है डी/सी आपको यह जानने के बिना कि आपको नेटवर्क स्ट्रीम पढ़ने के रूप में कोई डेटा नहीं मिलता है लेकिन डेटा में कोई त्रुटि नहीं होती है। –

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