सॉकेट.शटडाउन बनाम सॉकेट.क्लोज


122

मैंने हाल ही में एक सा कोड देखा, जो इस तरह दिखता था (सॉकेट ऑब्जेक्ट होने के नाते)

sock.shutdown(socket.SHUT_RDWR)
sock.close()

सॉकेट पर शटडाउन को कॉल करने और फिर इसे बंद करने का वास्तव में क्या उद्देश्य है? यदि इससे कोई फर्क पड़ता है, तो इस सॉकेट का उपयोग गैर-अवरुद्ध IO के लिए किया जा रहा है।

जवाबों:


38

यहाँ एक स्पष्टीकरण है :

एक बार सॉकेट की आवश्यकता नहीं होने पर, कॉलिंग प्रोग्राम सॉकेट डिस्क्रिप्टर के करीब सबरूटीन लगाकर सॉकेट को छोड़ सकता है। यदि किसी विश्वसनीय डिलीवरी सॉकेट में डेटा सम्‍मिलित है, जब कोई क्लोज होता है, तो सिस्टम डेटा ट्रांसफर का प्रयास जारी रखता है। हालाँकि, यदि डेटा अभी भी पूर्ववत नहीं है, तो सिस्टम डेटा को हटा देता है। क्या एप्लिकेशन प्रोग्राम का किसी भी लंबित डेटा के लिए कोई उपयोग नहीं है, इसे बंद करने से पहले सॉकेट पर शटडाउन सबरूटीन का उपयोग कर सकते हैं।


241

कॉलिंग closeऔर shutdownअंतर्निहित सॉकेट पर दो अलग-अलग प्रभाव होते हैं।

पहली बात यह है कि सॉकेट अंतर्निहित ओएस में एक संसाधन है और कई प्रक्रियाओं में एक ही अंतर्निहित सॉकेट के लिए एक हैंडल हो सकता है।

जब आप कहते हैं closeकि यह एक से हैंडल काउंट को घटाता है और यदि हैंडल की संख्या शून्य तक पहुंच गई है तो सॉकेट और संबंधित कनेक्शन सामान्य क्लोज प्रक्रिया (प्रभावी रूप से सहकर्मी को फिन / ईओएफ भेजना) के माध्यम से चला जाता है और सॉकेट को हटा दिया जाता है।

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

दूसरी ओर shutdown, पढ़ने और लिखने के लिए कॉल करना अंतर्निहित कनेक्शन को बंद कर देता है और पीयर को एक फिन / ईओएफ भेजता है, भले ही सॉकेट में कितनी प्रक्रियाएं हों। हालांकि, यह सॉकेट को नहीं करता है और आपको अभी भी बाद में कॉल करने की आवश्यकता है।


महान जवाब, मैं यह पता लगाने के लिए कभी परेशान नहीं हुआ कि shutdown():)
मैट जॉइनर

2
क्या रीड के लिए शटडाउन () के कारण फिन पैकेट भेजा जा सकता है? यानी शटडाउन (sock_fd, 1);
एर्नेस्टो

क्या हमेशा कॉल करना .shutdown()और अगली पंक्ति में स्मार्ट होगा .close()? या बीच में देरी होनी चाहिए?
ल्यूक

@ पूरी तरह से आप क्या कर रहे हैं पर निर्भर करता है।
रॉबर्ट एस। बार्न्स

2
@ तब तक करीब ठीक है जब तक कि किसी अन्य प्रक्रिया में सॉकेट के लिए एक हैंडल नहीं है।
रॉबर्ट एस। बार्न्स

17

शटडाउन और क्लोज का स्पष्टीकरण: ग्रेसफुल शटडाउन (msdn)

शटडाउन (आपके मामले में) कनेक्शन के दूसरे छोर को इंगित करता है कि सॉकेट से पढ़ने या लिखने का कोई और इरादा नहीं है। फिर सॉकेट से जुड़ी किसी भी मेमोरी को बंद कर देता है।

शटडाउन शटडाउन का कारण हो सकता है कि सॉकेट OSs स्टैक में जब तक कनेक्शन को इनायत से बंद नहीं किया जाता है, तब तक वह बंद रहता है।

IMO 'शटडाउन' और 'करीब' नाम भ्रामक हैं, 'करीब' और 'नष्ट' उनके मतभेदों पर जोर देंगे।


यह दूसरे छोर को इंगित नहीं करता है कि आगे पढ़ने का कोई इरादा नहीं है। पढ़ने के लिए शटडाउन सहकर्मी को कुछ भी नहीं भेजता है।
लोर्ने

7

यह सही सॉकेट प्रोग्रामिंग HOWTO ( py2 / py3 ) में उल्लिखित है

डिस्कनेक्ट कर रहा है

कड़ाई से बोलते हुए, shutdownइससे पहले कि आप closeइसे सॉकेट पर उपयोग करने वाले हैं । shutdownदूसरे छोर पर सॉकेट करने के लिए एक सलाहकार है। आपके द्वारा पास किए गए तर्क के आधार पर, इसका मतलब हो सकता है " मैं अब भेजने नहीं जा रहा हूं, लेकिन मैं अभी भी सुनूंगा ", या " मैं नहीं सुन रहा हूं, अच्छी लकीर! "। हालाँकि, अधिकांश सॉकेट लाइब्रेरीज़, प्रोग्रामर के लिए इस्तेमाल की जाती हैं, जो कि शिष्टाचार के इस टुकड़े का उपयोग करने की उपेक्षा कर रहे हैं, जो सामान्य रूप से एक closeही है shutdown(); close()। इसलिए ज्यादातर स्थितियों में, एक स्पष्ट बंद की आवश्यकता नहीं है।

...


यह जानकारी सही नहीं है। यह लिखने के लिए केवल एक सॉकेट बंद करना कभी आवश्यक है अगर (1) आपने प्रक्रिया को छोड़ दिया है और निश्चित रूप से अब एफआई ​​को भेजना चाहते हैं, या (2) आप एक आपसी रीड-टू-ईओएस प्रोटोकॉल में संलग्न हैं, जैसे कि दोनों सहकर्मी करीब एक ही समय में। अन्यथा close()पर्याप्त है। पायथन प्रलेखन को सही किया जाना चाहिए।
लोर्ने

4

क्या यह कोड गलत नहीं है?

शटडाउन कॉल के बाद सीधे बंद कॉल कर्नेल को सभी आउटगोइंग बफ़र्स को वैसे भी बंद कर सकता है।

Http://blog.netherlabs.nl/articles/2009/01/18/the-ultimate-so_linger-page-or-why-is-my-tcp-not-reliable के अनुसार शटडाउन और के बीच इंतजार करने की जरूरत है करीब जब तक पढ़ें रिटर्न 0।


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

3

शटडाउन के कुछ स्वाद हैं: http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.shutdown.aspx । * निक्स समान है।


शटडाउन का एक 'स्वाद' है, और इसके दो विकल्प हैं, जिन्हें जोड़ा जा सकता है। यहां कुछ भी वास्तविक प्रश्न का उत्तर नहीं देता है।
लोर्ने

1

शटडाउन (1), सॉकेट को और अधिक डेटा भेजने के लिए मजबूर करता है

इसमें उपयोगी है

1- बफर फ्लशिंग

2- अजीब त्रुटि का पता लगाना

3- सुरक्षित रखवाली

मुझे और समझाएं, जब आप A से B का डेटा भेजते हैं, तो इसे B को भेजे जाने की गारंटी नहीं है, यह केवल A os बफर को भेजे जाने की गारंटी है, जो बदले में इसे B os बफर को भेजता है।

इसलिए A पर शटडाउन (1) कॉल करके, आप A के बफर को फ्लश करते हैं और यदि बफर खाली नहीं है तो एक त्रुटि उठाई जाती है: डेटा अभी तक सहकर्मी को नहीं भेजा गया है

जब भी यह अपरिवर्तनीय होता है, तो आप यह कर सकते हैं कि आपके द्वारा अपना सारा डेटा भेजने के बाद और आप सुनिश्चित होना चाहते हैं कि यह सहकर्मी ओएस बफर में कम से कम है


शटडाउन एक फ्लश मजबूर नहीं करता है। बफरिंग की स्थिति अपरिवर्तित है। और अगर बफर खाली नहीं है तो कोई त्रुटि नहीं उठाई जाती है। फिन केवल लंबित डेटा के पीछे संलग्न है। उत्तर पूरी तरह से गलत है।
लोर्ने
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.