it-swarm.asia

socket.shutdown مقابل socket.close

لقد رأيت مؤخرًا القليل من التعليمات البرمجية التي تبدو هكذا (مع كون الجورب كائن مقبس بالطبع):

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

ما هو بالضبط الغرض من الدعوة للإغلاق على المقبس ثم إغلاقه؟ إذا كان يحدث فرقًا ، فسيتم استخدام هذا المقبس في إدخال/إخراج غير محظور.

115
Jason Baker

إليك أحد الشرح :

بمجرد أن لم تعد هناك حاجة إلى مأخذ توصيل ، يمكن لبرنامج الاستدعاء تجاهل المقبس عن طريق تطبيق روتين فرعي قريب على واصف المقبس. إذا كان مأخذ التوصيل الموثوق به يحتوي على بيانات مرتبطة به عندما يتم الإغلاق ، فسيواصل النظام محاولة نقل البيانات. ومع ذلك ، إذا كانت البيانات لا تزال غير مُسلَّمة ، فإن النظام يتجاهل البيانات. في حالة عدم استخدام برنامج التطبيق لأي بيانات معلقة ، فيمكنه استخدام روتين إيقاف التشغيل على المقبس قبل إغلاقه.

35
Bob Nadler

استدعاء close و shutdown لهما تأثيران مختلفان على المقبس الأساسي.

أول شيء يجب الإشارة إليه هو أن المقبس هو مورد في نظام التشغيل الأساسي و يمكن أن يكون للعمليات المتعددة مقبض لنفس المقبس الأساسي.

عندما تقوم بالاتصال بـ close فإنه يقلل من عدد المقبض بواحد ، وإذا وصل عدد المقبض إلى صفر ، فإن المقبس والاتصال المرتبط به يمر عبر إجراء الإغلاق العادي (إرسال فعال FIN/EOF إلى النظير) مقبس deallocated.

الشيء الذي يجب الانتباه إليه هنا هو أنه إذا لم يصل عدد المقبض إلى الصفر لأن هناك عملية أخرى لا يزال لها مقبس للمقبس ، فلن يتم إغلاق الاتصال ولا يتم تخصيص المقبس.

من ناحية أخرى ، فإن استدعاء shutdown للقراءة والكتابة يغلق الاتصال الأساسي ويرسل FIN/EOF إلى النظير بغض النظر عن عدد العمليات التي لها مقابض إلى المقبس. ومع ذلك ، فإنه لا إلغاء تخصيص المقبس ولا تزال بحاجة إلى الاتصال وثيق بعد ذلك.

220
Robert S. Barnes

شرح الاغلاق والاغلاق: الاغلاق الرشيق (msdn)

يشير إيقاف التشغيل (في حالتك) إلى الطرف الآخر من الاتصال إلى عدم وجود نية أخرى للقراءة من المقبس أو الكتابة إليه. ثم يحرر الإغلاق أي ذاكرة مرتبطة بالمقبس.

قد يتسبب حذف الإغلاق في استمرار مأخذ التوصيل في مكدس أنظمة التشغيل حتى يتم إغلاق الاتصال بأمان.

IMO أسماء "إيقاف التشغيل" و "إغلاق" مضللة ، "إغلاق" و "تدمير" ستؤكد خلافاتهم.

18
Dale Reidy

لقد تم ذكرها في HOWTO Programming ( py2 / py3 )

قطع الاتصال

بالمعنى الدقيق للكلمة ، من المفترض أن تستخدم shutdown على مأخذ توصيل قبل close عليه. shutdown هو نصيحة إلى المقبس في الطرف الآخر. اعتمادًا على الوسيطة التي تمررها ، يمكن أن تعني "لن أرسل بعد الآن ، لكنني ما زلت أستمع" ، أو "أنا لا أستمع ، سخرية جيدة! ". ومع ذلك ، يتم استخدام معظم مكتبات مأخذ التوصيل للمبرمجين الذين يهملون استخدام هذه القطعة من الآداب التي عادةً ما تكون close هي نفس shutdown(); close(). لذلك في معظم الحالات ، لا يلزم إغلاق واضح.

...

7
mykhal

أليس هذا الرمز أعلاه خاطئ؟

قد تجعل المكالمة إغلاق مباشرة بعد استدعاء إيقاف تشغيل kernel تجاهل كافة المخازن المؤقتة الصادرة على أي حال.

وفقًا لـ http://blog.netherlabs.nl/articles/2009/01/18/the-ultimate-so_linger-page-or-why-is-my-tcp-not-reliable يحتاج المرء إلى انتظر بين الإغلاق والإغلاق حتى تعود القراءة 0.

5
Christian

هناك بعض النكهات للإغلاق: http://msdn.Microsoft.com/en-us/library/system.net.sockets.socket.shutdown.aspx . * لا شىء مماثل.

4
Ray Tayek

إيقاف التشغيل (1) ، يفرض على المقبس عدم إرسال المزيد من البيانات

هذا مفيد في

1 - عازلة فلاشينغ

2- اكتشاف خطأ غريب

3 - حراسة آمنة

اسمحوا لي أن أشرح أكثر ، عند إرسال بيانات من A إلى B ، لا يُضمن إرسالها إلى B ، بل يُضمن فقط إرسالها إلى المخزن المؤقت A ، والذي بدوره يقوم بإرسالها إلى المخزن المؤقت B os

لذلك عن طريق استدعاء إيقاف التشغيل (1) على A ، يمكنك مسح المخزن المؤقت الخاص بـ A ويحدث خطأ إذا لم يكن المخزن المؤقت فارغًا ، أي: لم يتم إرسال البيانات إلى النظير بعد

مهما كان هذا الأمر لا رجعة فيه ، يمكنك القيام بذلك بعد أن ترسل بياناتك بالكامل وتريد أن تتأكد من أنها على الأقل في المخزن المؤقت النظير

2
user306166