2009-02-05 11 views
33

यह पता लगाने के लिए कि क्या यह जुड़ा हुआ है, मुझे एक (टीसीपी) सॉकेट कैसे जांचनी चाहिए?मैं कैसे जांच सकता हूं कि एक (टीसीपी) सॉकेट (डी) सी # में जुड़ा हुआ है या नहीं?

मैंने संपत्ति MSDN में पढ़ी है, लेकिन यह कहता है कि यह केवल अंतिम I/O के अनुसार राज्य को दिखाता है। यह मेरे लिए उपयोगी नहीं है, क्योंकि मैं सॉकेट से पढ़ने की कोशिश कर रहे से पहले करना चाहता हूं। टिप्पणी अनुभाग भी लिखते हैं कि:

आप कनेक्शन की वर्तमान स्थिति का निर्धारण करने की जरूरत है, एक nonblocking, शून्य-बाइट संदेश फोन करना। यदि कॉल सफलतापूर्वक लौटाता है या एक WAEWOULDBLOCK त्रुटि कोड (10035) फेंकता है, तो सॉकेट अभी भी कनेक्ट है; अन्यथा, सॉकेट अब कनेक्ट नहीं है।

उसी पृष्ठ पर उदाहरण दिखाता है कि यह कैसे करें। (1) लेकिन a post by Ian Griffiths कहता है कि मुझे सॉकेट से पढ़ना चाहिए, इसके माध्यम से भेजें।

Another post by Pete Duniho कहते हैं: ...

के बाद आप Shutdown() बुलाया गया है, कॉल Receive() जब तक यह रिटर्न 0 (दूरस्थ endpoint संभालने नहीं है वास्तव में, आप कुछ भी भेजने जा कि होगा जैसे ही रिमोट एंडपॉइंट को आपके सभी डेटा प्राप्त हुए हैं)। जब तक आप ऐसा नहीं करते हैं, तो आपके पास कोई आश्वासन नहीं है कि रिमोट एंडपॉइंट वास्तव में आपके द्वारा भेजे गए सभी डेटा को प्राप्त किया गया है, यहां तक ​​कि सॉकेट का उपयोग करके भी भेजा गया है।

मैं वास्तव में Receive() बुला कि दूरदराज के endpoint वास्तव में सभी डेटा मैं भेजा प्राप्त हुआ है सुनिश्चित करने के लिए के बारे में अपने बयान समझ में नहीं आता। (भेजने वाले बफर खाली होने तक सॉकेट ब्लॉक प्राप्त करते हैं?)

मैं प्रस्तावित विभिन्न विधियों से उलझन में हूं। क्या आप उन्हें समझा सकते हैं?


(1) मुझे आश्चर्य है कि क्यों Socket.Connected संपत्ति के लिए example एक 1-बाइट सरणी आबंटित करता है, भले ही यह 0 लंबाई के साथ Send कॉल? एक सॉकेट की

+0

इस लिंक को चेक करें ... अंत में आप उस http://stackoverflow.com/questions/1387459/how-to-check-if-tcpclient-connection-is-closed – Operagust

उत्तर

21

मौत कई मायनों में अपने व्यवहार में बदलाव लाती है, तो इन तरीकों दोनों वैध :)

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

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

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

जब सॉकेट कनेक्ट होता है, Receive() तब तक अवरुद्ध हो जाएगा जब तक सॉकेट को रिक्त पेलोड के साथ एक पैकेट प्राप्त न हो जाए। लेकिन जब सॉकेट डिस्कनेक्ट हो जाता है, Receive() जैसे ही अंतिम ACK पैकेट आ जाएगा।

कॉलिंग Receive() कि आप या तो कि अपने रिमोट समाप्ति बिंदु या एक डिस्कनेक्ट टाइमआउट से पिछले ACK पैकेट होता है प्राप्त करते हैं और आप इस सॉकेट पर अधिक कुछ भी नहीं प्राप्त करने के लिए सक्षम हो जाएगा सुनिश्चित करता है।

उसी पृष्ठ पर उदाहरण दिखाता है कि यह कैसे करें। (मुझे आश्चर्य है कि यह 1-बाइट सरणी आवंटित क्यों करता है, भले ही यह 0 लंबाई के साथ भेजें?) लेकिन इयान ग्रिफिथ्स की एक पोस्ट कहती है कि मुझे सॉकेट से पढ़ना चाहिए, इसके माध्यम से नहीं भेजना चाहिए।

send() सॉकेट में आईएनजी, आप वास्तव में सॉकेट कतार के अंत में कुछ डेटा जोड़ने की कोशिश करते हैं। क्या बफर में कुछ जगह छोड़ी गई है, तो Send() तत्काल लौटाता है, यदि नहीं, तो Send() ब्लॉक कुछ जगह होने तक।

जब सॉकेट डिस्कनेक्ट स्थिति में है, TCP/IP स्टैक बफर के साथ सभी आगे के संचालन को रोकता है, इसलिए Send() त्रुटि देता है।

Send() एक मूल सूचक जांच लागू करता है, इसका मतलब है कि यह विफल रहता है जब NULL पॉइंटर पास हो जाता है। आप संभवतः किसी पॉइंटर के रूप में किसी भी गैर-निरंतर स्थिरता को पारित कर सकते हैं, लेकिन आप लगातार स्थिर होने के बजाय 1 बाइट आवंटित करते हैं - बस मामले में।


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

मेरे लिए, मैं Receive() पसंद करूंगा, क्योंकि यह सामान्य रूप से आप चक्र में दौड़ते हैं और प्रतीक्षा करते हैं। आपको Receive() से गैर-शून्य मिलता है, आप डेटा संसाधित करते हैं; आपको शून्य मिलता है, आप डिस्कनेक्शन को संसाधित करते हैं।

+0

के लिए एक प्रक्रिया पा सकते हैं धन्यवाद बहुत ! हालांकि मुझे अभी भी कुछ स्पष्टीकरण की आवश्यकता है। अगर मैं सॉकेट के माध्यम से कुछ भी नहीं भेजता, तो यह जांचने के लिए कौन सी विधि सबसे अच्छी है कि सॉकेट जीवित है इससे पढ़ने से पहले? क्या मुझे प्राप्त करने की कोशिश करनी चाहिए, और अगर मुझे 0 मिल जाए तो सॉकेट बंद कर दिया गया है? –

+0

उदाहरण भी 1-बाइट सरणी आवंटित क्यों करता है, और उसके बाद 0 लंबाई के साथ भेजने के लिए इसे पास करता है? क्या यह नया बाइट आवंटित करने से अलग है [0]? –

+0

मेरी अद्यतन पोस्ट – Quassnoi

1

आम तौर पर सॉकेट का उपयोग करेगा। सॉकेट के सेट की स्थिति निर्धारित करने के लिए विधि चुनें (सॉकेट.पॉल एक सॉकेट के लिए)।

इन दोनों विधियों से आप सॉकेट के राज्य से पूछ सकते हैं। अब, यह मानते हुए कि आपने ट्रैक किया है कि सॉकेट पहले स्थान पर जुड़ा हुआ है, तो आप आमतौर पर पढ़ने का प्रयास करने से पहले सॉकेट पर चयन/पोल को कॉल करेंगे। यदि चयन/पोल इंगित करता है कि सॉकेट पठनीय है तो यह आपको बताता है कि:

  • या तो सॉकेट में डेटा उपलब्ध शीर्ष पर पढ़ा गया है, इस मामले में प्राप्त करने के लिए उपलब्ध डेटा वापस लौटाएगा।
  • सॉकेट सॉकेट बंद कर दिया गया है, जिस स्थिति में जब आप 0 बाइट प्राप्त करते हैं तो तुरंत लौटा दिया जाएगा (यानी यदि चयन/पोल इंगित करता है कि सॉकेट पठनीय है और आप प्राप्त करते हैं तो कॉल प्राप्त होता है लेकिन यह तुरंत 0 बाइट्स के साथ वापस आता है तो आप जानते हैं कि कनेक्शन को बंद कर दिया गया है, रीसेट या समाप्त कर दिया गया है।

व्यक्तिगत रूप से मैंने कभी भी मतदान का उपयोग नहीं किया है - मैंने हमेशा चयन का उपयोग किया है लेकिन एमएसडीएन का सुझाव है कि मतदान चयन के समान ही है लेकिन एकल सॉकेट के लिए है।

मैं यह भी जोड़ूंगा कि चयन का उपयोग करके ज्यादातर मामलों में सॉकेट कनेक्शन को संभालने का सबसे प्रभावी और सबसे अच्छा तरीका है।

+1

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

+0

... क्या आप कृपया इस तरह के मामलों को संभालने का उदाहरण दे सकते हैं? –

4

"यदि आपको कनेक्शन की वर्तमान स्थिति निर्धारित करने की आवश्यकता है, तो एक गैर-ब्लॉकिंग, शून्य-बाइट भेजें कॉल करें। अगर कॉल सफलतापूर्वक लौटता है या WAEWOULDBLOCK त्रुटि कोड (10035) फेंकता है, तो सॉकेट अभी भी जुड़ा हुआ है, अन्यथा , सॉकेट अब कनेक्ट नहीं है। " दुर्भाग्य से, यह भी काम नहीं करता है!

mySocket.Blocking = false; 
byte[] buffer = new byte[1]; 
int iSent = mySocket.Send(buffer, 0, SocketFlags.None); 
bConnected = mySocket.Connected; 

bConnected हमेशा की तरह सच समाप्त होता है, और कॉल हमेशा सफलतापूर्वक देता है, भले ही ईथरनेट केबल अनप्लग किया गया है।

इसके अलावा, और दुर्भाग्यवश == किसी भी वास्तविक डेटा को भेजने से टूटे हुए कनेक्शन का पता नहीं चलता है।

buffer[0] = 0xff ; 
int iSent = mySocket.Send(buffer, 1, SocketFlags.None); 

बार-बार 1 लौटाता है, जैसे कि अगर वास्तव में कुछ भेजा गया हो। हालांकि सवाल में डिवाइस अब भी जुड़ा हुआ नहीं है।

+1

मुझे लगता है कि (तारकीय से कम) एमएसडीएन उदाहरण है कि आपको अपवादों को संभालना था और अपवाद के मामले में मैन्युअल रूप से झूठी वापसी करना था। वह सॉकेट है। कनेक्ट किए गए मान में अपवाद के बाद एक अवैध मान हो सकता है। यदि आप अपवादों को मैन्युअल रूप से प्रबंधित कर रहे हैं तो अपने कोड स्निपेट से नहीं बता सकते हैं। – Tod

1

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

@PeteDuniho द्वारा पोस्ट कनेक्शन की स्थिति स्थापित करने के बारे में नहीं है, यह इस तरह से कनेक्शन को समाप्त करने के बारे में है कि आप जानते हैं कि सहकर्मी को आपका पूरा डेटा कब प्राप्त हुआ है।

(जब तक भेजने के बफर खाली है सॉकेट प्राप्त अवरोधित करूँ?)

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

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

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