คู่มือเกมแลค › L8 ซ็อกเก็ตและโปรโตคอล
ข้อมูลสุดท้ายหายเพราะปิดการเชื่อมต่อแบบบังคับ (RST) SO_LINGER, abrupt RST
ID สาเหตุ sk-linger · ผู้รับผิดชอบหลัก พัฒนาเซิร์ฟเวอร์ (ทีมพัฒนาเกม)
เปิดการ์ดในฉบับหลักที่มีภาพและการทดลอง →
ถ้าเซิร์ฟเวอร์ตัดการเชื่อมต่อแบบกะทันหัน ข้อความแจ้งสุดท้ายหรือสัญญาณว่าบันทึกข้อมูลเสร็จที่ส่งออกไปจะหายไป
ทำไม เซิร์ฟเวอร์ปิดการเชื่อมต่อแบบบังคับ (RST) เกิดเมื่อตั้ง SO_LINGER เป็น 0 วินาที หรือปิดทั้งที่ยังอ่านข้อมูลที่รับมาไม่หมด → ผลคือ เหตุผลที่ถูกเตะออก (kick) และข้อมูลสุดท้ายที่ยังส่งไม่ถึงถูกทิ้ง → บนหน้าจอ ขึ้นข้อความ “การเชื่อมต่อถูกตัดเนื่องจากข้อผิดพลาดที่ไม่ทราบสาเหตุ” โดยไม่รู้เหตุผล
- อาการ
- หลุด
- ปัจจัย
- แพ็กเก็ตหาย
- ใครเจอ
- เราคนเดียว
- เกิดเมื่อไร
- สุ่มเป็นครั้งคราว
- ผู้รับผิดชอบ
- ผู้รับผิดชอบหลัก พัฒนาเซิร์ฟเวอร์ (ทีมพัฒนาเกม)
- งานฝั่งทีมพัฒนาเกม
- ส่งเหตุผลแล้วปิดเฉพาะทิศทางส่งก่อน (shutdown) อ่านข้อมูลที่รับเข้ามาจนอีกฝั่งปิด แล้วจึงปิดซ็อกเก็ต, เลี่ยง SO_LINGER 0 วินาที
- บนกราฟ
- พุ่งแบบสุ่มเป็นครั้งคราว · จำนวนการเชื่อมต่อที่จบด้วย RST
- จุดที่ต้องดู
- ค่าที่เพิ่มขึ้นของ TcpExtTCPAbortOnData (ปิดด้วย RST ขณะที่ยังมีข้อมูลรอส่ง, SO_LINGER 0 วินาที) และ TcpExtTCPAbortOnClose (ปิดขณะที่ยังมีข้อมูลที่ยังไม่ได้อ่าน) จาก nstat -az และดูใน packet capture ฝั่งเซิร์ฟเวอร์ตอนที่หลุดว่าส่ง RST ออกไปแทน FIN หรือไม่
- สัญญาณว่าใช่
- ตรงกับเวลาที่ผู้เล่นแจ้งว่าขึ้น “การเชื่อมต่อถูกตัดเนื่องจากข้อผิดพลาดที่ไม่ทราบสาเหตุ” เซิร์ฟเวอร์ส่ง RST และ AbortOnData กับ AbortOnClose เพิ่มขึ้น
- สัญญาณว่าไม่ใช่
- เซิร์ฟเวอร์ปิดตามปกติด้วย FIN แต่ผู้เล่นไม่เห็นเหตุผล: น่าจะเป็นการจัดการตอนปิดของไคลเอนต์
- วิธีตรวจ
- ใช้เครื่องมือฝั่งอินฟรา (ไม่ต้องใช้โค้ดเกม)
แหล่งอ้างอิง
- closesocket function (winsock.h) Microsoft
ถ้าเปิด SO_LINGER และตั้งเวลาเป็น 0 การปิดจะกลายเป็นการปิดแบบบังคับที่รีเซ็ตการเชื่อมต่อทันที และข้อมูลที่ยังส่งไม่ออกจะหายไป - RFC 9293: Transmission Control Protocol (TCP) IETF
ถ้าปิดขณะที่ยังมีข้อมูลที่รับมาแต่ยังไม่ได้อ่าน จะส่ง RST เพื่อแจ้งว่าข้อมูลสูญหาย - Graceful Shutdown, Linger Options, and Socket Closure Microsoft
ลำดับคือใช้ shutdown ปิดเฉพาะฝั่งส่งก่อน แล้วปิดซ็อกเก็ตหลังได้รับการแจ้งปิดจากอีกฝั่ง - SNMP counter Linux kernel
TcpExtTCPAbortOnData: ปิดด้วย RST ขณะที่ยังมีข้อมูลรอส่ง (เช่น SO_LINGER 0 วินาที), TcpExtTCPAbortOnClose: ปิดขณะที่ยังมีข้อมูลที่ยังไม่ได้อ่านจึงส่ง RST
สาเหตุที่ควรดูประกอบ
ชั้นเดียวกัน: L8 ซ็อกเก็ตและโปรโตคอล
สาเหตุจากชั้นอื่นที่ทำให้เกิดอาการเดียวกัน (หลุด)
ดูการ์ดในฉบับหลักที่มีภาพและการทดลอง