ฉันเพิ่งเห็นรหัสเล็กน้อยที่มีลักษณะเช่นนี้ (แน่นอนว่าถุงเท้าเป็นวัตถุซ็อกเก็ต):
sock.shutdown(socket.SHUT_RDWR)
sock.close()
จุดประสงค์ของการเรียกการปิดระบบบนซ็อกเก็ตแล้วปิดมันคืออะไร? หากสร้างความแตกต่างซ็อกเก็ตนี้จะถูกใช้สำหรับ IO ที่ไม่ปิดกั้น
ฉันเพิ่งเห็นรหัสเล็กน้อยที่มีลักษณะเช่นนี้ (แน่นอนว่าถุงเท้าเป็นวัตถุซ็อกเก็ต):
sock.shutdown(socket.SHUT_RDWR)
sock.close()
จุดประสงค์ของการเรียกการปิดระบบบนซ็อกเก็ตแล้วปิดมันคืออะไร? หากสร้างความแตกต่างซ็อกเก็ตนี้จะถูกใช้สำหรับ IO ที่ไม่ปิดกั้น
คำตอบ:
นี่คือหนึ่งคำอธิบาย :
เมื่อไม่จำเป็นต้องใช้ซ็อกเก็ตอีกต่อไปโปรแกรมการโทรสามารถยกเลิกซ็อกเก็ตได้โดยใช้รูทีนย่อยที่ใกล้เคียงกับตัวอธิบายซ็อกเก็ต หากซ็อกเก็ตการจัดส่งที่เชื่อถือได้มีข้อมูลที่เกี่ยวข้องเมื่อเกิดการปิดระบบจะพยายามถ่ายโอนข้อมูลต่อไป อย่างไรก็ตามหากยังไม่ได้ส่งข้อมูลระบบจะทิ้งข้อมูลนั้น หากโปรแกรมแอปพลิเคชันไม่มีการใช้งานสำหรับข้อมูลใด ๆ ที่รอดำเนินการโปรแกรมสามารถใช้รูทีนย่อยการปิดระบบบนซ็อกเก็ตก่อนที่จะปิด
การโทรcloseและshutdownมีผลกระทบที่แตกต่างกันสองแบบในซ็อกเก็ต
สิ่งแรกที่ต้องชี้ให้เห็นก็คือซ็อกเก็ตเป็นทรัพยากรในระบบปฏิบัติการพื้นฐานและกระบวนการต่างๆสามารถมีจุดจับสำหรับซ็อกเก็ตพื้นฐานเดียวกันได้
เมื่อคุณเรียกcloseมันว่าการลดจำนวนแฮนเดิลลงทีละรายการและหากจำนวนแฮนเดิลถึงศูนย์ดังนั้นซ็อกเก็ตและการเชื่อมต่อที่เกี่ยวข้องจะดำเนินการตามขั้นตอนการปิดตามปกติ (ส่ง FIN / EOF ไปยังเพียร์อย่างมีประสิทธิภาพ) และซ็อกเก็ตจะถูกยกเลิกการจัดสรร
สิ่งที่ต้องใส่ใจในที่นี้ก็คือหากจำนวนที่จับไม่ถึงศูนย์เนื่องจากกระบวนการอื่นยังคงมีที่จับเข้ากับซ็อกเก็ตการเชื่อมต่อจะไม่ปิดและซ็อกเก็ตจะไม่ถูกจัดสรร
ในทางกลับกันการเรียกร้องshutdownให้อ่านและเขียนจะปิดการเชื่อมต่อพื้นฐานและส่ง FIN / EOF ไปยังเพียร์โดยไม่คำนึงถึงจำนวนกระบวนการที่จัดการกับซ็อกเก็ต อย่างไรก็ตามจะไม่ยกเลิกการจัดสรรซ็อกเก็ตและคุณยังต้องโทรปิดในภายหลัง
.shutdown()และในบรรทัดถัดไป.close()? หรือควรมีความล่าช้าในระหว่าง?
คำอธิบายของการปิดและปิด: การปิดเครื่องอย่างสง่างาม (msdn)
การปิดเครื่อง (ในกรณีของคุณ) ระบุว่าปลายอีกด้านหนึ่งของการเชื่อมต่อไม่มีความตั้งใจที่จะอ่านหรือเขียนไปยังซ็อกเก็ตอีกต่อไป จากนั้นปิดจะเพิ่มหน่วยความจำที่เกี่ยวข้องกับซ็อกเก็ต
การละเว้นการปิดเครื่องอาจทำให้ซ็อกเก็ตค้างอยู่ในสแต็ก OS จนกว่าการเชื่อมต่อจะถูกปิดอย่างสวยงาม
IMO ชื่อ 'ปิดระบบ' และ 'ปิด' ทำให้เข้าใจผิด 'ปิด' และ 'ทำลาย' จะเน้นความแตกต่าง
ถูกกล่าวถึงใน Socket Programming HOWTO ( py2 / py3 )
ยกเลิกการเชื่อมต่อ
อย่างเคร่งครัดพูดที่คุณควรจะใช้
shutdownในซ็อกเก็ตก่อนที่คุณจะcloseมันshutdownเป็นที่ปรึกษาให้กับซ็อกเก็ตที่ปลายอื่น ๆ ขึ้นอยู่กับข้อโต้แย้งที่คุณส่งผ่านมันอาจหมายถึง“ ฉันจะไม่ส่งอีกต่อไป แต่ฉันจะยังฟัง ” หรือ“ ฉันไม่ฟังหรอกนะปริศนาดี! ” อย่างไรก็ตามไลบรารีซ็อกเก็ตส่วนใหญ่มักใช้กับโปรแกรมเมอร์ที่ละเลยที่จะใช้มารยาทนี้ซึ่งโดยปกติแล้ว acloseจะเหมือนกับshutdown(); close()ไฟล์. ดังนั้นในสถานการณ์ส่วนใหญ่จึงไม่จำเป็นต้องปิดระบบอย่างชัดเจน...
close()ก็เพียงพอแล้ว เอกสาร Python ควรได้รับการแก้ไข
รหัสข้างบนนี้ไม่ผิดใช่ไหม
การโทรปิดโดยตรงหลังจากการเรียกปิดเครื่องอาจทำให้เคอร์เนลละทิ้งบัฟเฟอร์ขาออกทั้งหมดอยู่ดี
อ้างอิงจาก http://blog.netherlabs.nl/articles/2009/01/18/the-ultimate-so_linger-page-or-why-is-my-tcp-not-reliable ต้องรอระหว่างการปิดและ ปิดจนกว่าการอ่านจะส่งกลับ 0
มีรสชาติของการปิดบางส่วน: http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.shutdown.aspx * nix คล้ายกัน
ปิดเครื่อง (1) บังคับไม่ให้ซ็อกเก็ตส่งข้อมูลเพิ่มเติม
นี่เป็นประโยชน์ใน
1- การล้างบัฟเฟอร์
2- การตรวจจับข้อผิดพลาดแปลก ๆ
3- การป้องกันที่ปลอดภัย
ให้ฉันอธิบายเพิ่มเติมเมื่อคุณส่งข้อมูลจาก A ไป B ไม่รับประกันว่าจะถูกส่งไปยัง B แต่รับประกันว่าจะถูกส่งไปยังบัฟเฟอร์ A os เท่านั้นซึ่งจะส่งไปยังบัฟเฟอร์ B os
ดังนั้นด้วยการเรียก shutdown (1) บน A คุณจะล้างบัฟเฟอร์ของ A และข้อผิดพลาดจะเพิ่มขึ้นหากบัฟเฟอร์ไม่ว่างเปล่านั่นคือ: ข้อมูลยังไม่ถูกส่งไปยังเพียร์
อย่างไรก็ตามสิ่งนี้ไม่สามารถเรียกคืนได้ดังนั้นคุณสามารถทำได้หลังจากที่คุณส่งข้อมูลทั้งหมดของคุณจนหมดและคุณต้องการให้แน่ใจว่ามันเป็นอย่างน้อยที่สุดที่บัฟเฟอร์ระบบปฏิบัติการเพียร์
shutdown()ทำอะไร:)