การตั้งค่าการเชื่อมต่อ TCP
เมื่อเราท่องเว็บ ส่งอีเมล หรือเล่นเกมออนไลน์ เรามักจะไม่ได้คำนึงถึงการเชื่อมต่อเครือข่ายที่ซับซ้อนเบื้องหลัง อย่างไรก็ตาม มันเป็นขั้นตอนที่ดูเหมือนเล็กๆ เหล่านี้ที่ทำให้มั่นใจได้ถึงการสื่อสารที่เสถียรระหว่างเราและเซิร์ฟเวอร์ ขั้นตอนที่สำคัญที่สุดอย่างหนึ่งคือการตั้งค่าการเชื่อมต่อ TCP และหัวใจสำคัญของขั้นตอนนี้คือการจับมือแบบสามทาง
บทความนี้จะกล่าวถึงหลักการ กระบวนการ และความสำคัญของการจับมือสามทางโดยละเอียด เราจะอธิบายทีละขั้นตอนว่าเหตุใดจึงจำเป็นต้องมีการจับมือแบบสามทาง วิธีทำให้มั่นใจในความเสถียรและความน่าเชื่อถือในการเชื่อมต่อ และความสำคัญของการถ่ายโอนข้อมูล ด้วยความเข้าใจที่ลึกซึ้งยิ่งขึ้นเกี่ยวกับการจับมือแบบสามทาง เราจะมีความเข้าใจที่ดีขึ้นเกี่ยวกับกลไกพื้นฐานของการสื่อสารเครือข่าย และมุมมองที่ชัดเจนยิ่งขึ้นเกี่ยวกับความน่าเชื่อถือของการเชื่อมต่อ TCP
กระบวนการจับมือสามทาง TCP และการเปลี่ยนสถานะ
TCP เป็นโปรโตคอลการขนส่งเชิงการเชื่อมต่อ ซึ่งจำเป็นต้องมีการสร้างการเชื่อมต่อก่อนการส่งข้อมูล กระบวนการสร้างการเชื่อมต่อนี้ทำได้โดยการจับมือสามทาง
มาดูแพ็กเก็ต TCP ที่ส่งในแต่ละการเชื่อมต่อกันดีกว่า
เริ่มแรกทั้งไคลเอนต์และเซิร์ฟเวอร์ถูกปิด ขั้นแรก เซิร์ฟเวอร์จะรับฟังพอร์ตและอยู่ในสถานะ LISTEN ซึ่งหมายความว่าเซิร์ฟเวอร์จะต้องเริ่มทำงาน ขั้นต่อไป ลูกค้าก็พร้อมที่จะเริ่มเข้าถึงหน้าเว็บ โดยจำเป็นต้องสร้างการเชื่อมต่อกับเซิร์ฟเวอร์ รูปแบบของแพ็กเก็ตการเชื่อมต่อแรกมีดังนี้:
เมื่อไคลเอ็นต์เริ่มต้นการเชื่อมต่อ จะสร้างหมายเลขลำดับเริ่มต้นแบบสุ่ม (client_isn) และวางไว้ในช่อง "หมายเลขลำดับ" ของส่วนหัว TCP ในเวลาเดียวกัน ไคลเอนต์ตั้งค่าตำแหน่งแฟล็ก SYN เป็น 1 เพื่อระบุว่าแพ็กเก็ตขาออกคือแพ็กเก็ต SYN ไคลเอนต์ระบุว่าต้องการสร้างการเชื่อมต่อกับเซิร์ฟเวอร์โดยการส่งแพ็กเก็ต SYN แรกไปยังเซิร์ฟเวอร์ แพ็กเก็ตนี้ไม่มีข้อมูลเลเยอร์แอปพลิเคชัน (นั่นคือ ข้อมูลที่ส่ง) ณ จุดนี้ สถานะของลูกค้าจะถูกทำเครื่องหมายเป็น SYN-SENT
เมื่อเซิร์ฟเวอร์ได้รับแพ็กเก็ต SYN จากไคลเอ็นต์ เซิร์ฟเวอร์จะสุ่มเตรียมใช้งานหมายเลขซีเรียลของตัวเอง (server_isn) จากนั้นจึงใส่หมายเลขนั้นลงในช่อง "หมายเลขซีเรียล" ของส่วนหัว TCP ถัดไป เซิร์ฟเวอร์ป้อน client_isn + 1 ในช่อง "หมายเลขการตอบรับ" และตั้งค่าทั้งบิต SYN และ ACK เป็น 1 สุดท้าย เซิร์ฟเวอร์จะส่งแพ็กเก็ตไปยังไคลเอนต์ ซึ่งไม่มีข้อมูลชั้นแอปพลิเคชัน (และไม่มีข้อมูลสำหรับเซิร์ฟเวอร์ เพื่อส่ง) ในขณะนี้ เซิร์ฟเวอร์อยู่ในสถานะ SYN-RCVD
เมื่อไคลเอนต์ได้รับแพ็กเก็ตจากเซิร์ฟเวอร์ จะต้องดำเนินการปรับให้เหมาะสมต่อไปนี้เพื่อตอบสนองต่อแพ็กเก็ตตอบกลับสุดท้าย: ขั้นแรก ไคลเอนต์ตั้งค่าบิต ACK ของส่วนหัว TCP ของแพ็กเก็ตตอบกลับเป็น 1; ประการที่สอง ลูกค้าป้อนค่า server_isn + 1 ในช่อง "ยืนยันหมายเลขคำตอบ" ในที่สุดไคลเอนต์จะส่งแพ็กเก็ตไปยังเซิร์ฟเวอร์ แพ็กเก็ตนี้สามารถนำข้อมูลจากไคลเอ็นต์ไปยังเซิร์ฟเวอร์ได้ เมื่อเสร็จสิ้นการดำเนินการเหล่านี้ ลูกค้าจะเข้าสู่สถานะที่จัดตั้งขึ้น
เมื่อเซิร์ฟเวอร์ได้รับแพ็กเก็ตตอบกลับจากไคลเอนต์ เซิร์ฟเวอร์จะสลับไปยังสถานะ ESTABLISHED ด้วย
ดังที่คุณเห็นจากกระบวนการข้างต้น เมื่อทำการจับมือแบบสามทาง การจับมือครั้งที่สามจะได้รับอนุญาตให้ส่งข้อมูล แต่การจับมือสองครั้งแรกไม่สามารถทำได้ นี่เป็นคำถามที่มักถูกถามในการสัมภาษณ์ เมื่อการจับมือแบบสามทางเสร็จสมบูรณ์ ทั้งสองฝ่ายจะเข้าสู่สถานะ ESTABLISHED ซึ่งบ่งชี้ว่าการเชื่อมต่อได้สำเร็จแล้ว ณ จุดนี้ไคลเอนต์และเซิร์ฟเวอร์สามารถเริ่มส่งข้อมูลถึงกัน
ทำไมต้องจับมือกันสามครั้ง? ไม่ใช่สองครั้งสี่ครั้งเหรอ?
คำตอบที่พบบ่อยคือ "เพราะการจับมือสามทางรับประกันความสามารถในการรับและส่ง" คำตอบนี้ถูกต้อง แต่เป็นเพียงเหตุผลผิวเผินเท่านั้น ไม่ได้หยิบยกเหตุผลหลักขึ้นมา ต่อไปนี้ ผมจะวิเคราะห์สาเหตุของการจับมือกันสามครั้งจากสามประเด็น เพื่อทำความเข้าใจปัญหานี้ให้ลึกซึ้งยิ่งขึ้น
การจับมือแบบสามทางสามารถหลีกเลี่ยงการเริ่มต้นการเชื่อมต่อซ้ำในอดีตได้อย่างมีประสิทธิภาพ (เหตุผลหลัก)
การจับมือกันสามทางรับประกันว่าทั้งสองฝ่ายจะได้รับหมายเลขลำดับเริ่มต้นที่เชื่อถือได้
การจับมือสามทางช่วยหลีกเลี่ยงการสิ้นเปลืองทรัพยากร
เหตุผลที่ 1: หลีกเลี่ยงการรวมที่ซ้ำกันในอดีต
โดยสรุป สาเหตุหลักของการจับมือแบบสามทางคือเพื่อหลีกเลี่ยงความสับสนที่เกิดจากการเริ่มต้นการเชื่อมต่อซ้ำซ้อนแบบเก่า ในสภาพแวดล้อมเครือข่ายที่ซับซ้อน การส่งแพ็กเก็ตข้อมูลไม่ได้ถูกส่งไปยังโฮสต์ปลายทางเสมอไปตามเวลาที่กำหนด และแพ็กเก็ตข้อมูลเก่าอาจมาถึงโฮสต์ปลายทางก่อน เนื่องจากความแออัดของเครือข่ายและเหตุผลอื่นๆ เพื่อหลีกเลี่ยงปัญหานี้ TCP จะใช้การจับมือแบบสามทางเพื่อสร้างการเชื่อมต่อ
เมื่อไคลเอ็นต์ส่งแพ็กเก็ตการสร้างการเชื่อมต่อ SYN หลายรายการติดต่อกัน ในสถานการณ์เช่นความแออัดของเครือข่าย สิ่งต่อไปนี้อาจเกิดขึ้น:
1- แพ็กเก็ต SYN เก่ามาถึงเซิร์ฟเวอร์ก่อนแพ็กเก็ต SYN ล่าสุด
2- เซิร์ฟเวอร์จะตอบกลับแพ็กเก็ต SYN + ACK ไปยังไคลเอนต์หลังจากได้รับแพ็กเก็ต SYN เก่า
3- เมื่อไคลเอนต์ได้รับแพ็กเก็ต SYN + ACK มันจะกำหนดว่าการเชื่อมต่อนั้นเป็นการเชื่อมต่อในอดีต (หมายเลขลำดับหมดอายุหรือหมดเวลา) ตามบริบทของตัวเอง จากนั้นจะส่งแพ็กเก็ต RST ไปยังเซิร์ฟเวอร์เพื่อยกเลิกการเชื่อมต่อ
ด้วยการเชื่อมต่อแบบ two-handshake ไม่มีทางที่จะระบุได้ว่าการเชื่อมต่อปัจจุบันเป็นการเชื่อมต่อในอดีตหรือไม่ การจับมือแบบสามทางช่วยให้ไคลเอ็นต์สามารถระบุได้ว่าการเชื่อมต่อปัจจุบันเป็นการเชื่อมต่อในอดีตหรือไม่ โดยขึ้นอยู่กับบริบทเมื่อพร้อมที่จะส่งแพ็กเก็ตที่สาม:
1- หากเป็นการเชื่อมต่อในอดีต (หมายเลขลำดับหมดอายุหรือหมดเวลา) แพ็กเก็ตที่ส่งโดยการจับมือครั้งที่สามจะเป็นแพ็กเก็ต RST ที่จะยกเลิกการเชื่อมต่อในอดีต
2- หากไม่ใช่การเชื่อมต่อในอดีต แพ็กเก็ตที่ส่งเป็นครั้งที่สามจะเป็นแพ็กเก็ต ACK และทั้งสองฝ่ายที่สื่อสารกันสามารถสร้างการเชื่อมต่อได้สำเร็จ
ดังนั้น เหตุผลหลักที่ TCP ใช้การจับมือแบบสามทางก็คือ เริ่มต้นการเชื่อมต่อเพื่อป้องกันการเชื่อมต่อในอดีต
เหตุผลที่ 2: เพื่อซิงโครไนซ์หมายเลขลำดับเริ่มต้นของทั้งสองฝ่าย
โปรโตคอล TCP ทั้งสองด้านจะต้องรักษาหมายเลขลำดับ ซึ่งเป็นปัจจัยสำคัญเพื่อให้แน่ใจว่าการส่งข้อมูลมีความน่าเชื่อถือ หมายเลขลำดับมีบทบาทสำคัญในการเชื่อมต่อ TCP โดยทำหน้าที่ดังต่อไปนี้:
ผู้รับสามารถกำจัดข้อมูลที่ซ้ำกันและรับรองความถูกต้องของข้อมูล
ผู้รับสามารถรับแพ็คเก็ตตามลำดับหมายเลขเพื่อให้แน่ใจว่าข้อมูลมีความสมบูรณ์
● หมายเลขลำดับสามารถระบุแพ็กเก็ตข้อมูลที่อีกฝ่ายได้รับ ทำให้สามารถรับส่งข้อมูลได้อย่างน่าเชื่อถือ
ดังนั้น เมื่อสร้างการเชื่อมต่อ TCP ไคลเอ็นต์จะส่งแพ็กเก็ต SYN พร้อมหมายเลขลำดับเริ่มต้น และต้องการให้เซิร์ฟเวอร์ตอบกลับด้วยแพ็กเก็ต ACK ซึ่งบ่งชี้ว่าการรับแพ็กเก็ต SYN ของไคลเอ็นต์สำเร็จ จากนั้น เซิร์ฟเวอร์จะส่งแพ็กเก็ต SYN พร้อมหมายเลขลำดับเริ่มต้นไปยังไคลเอ็นต์ และรอให้ไคลเอ็นต์ตอบกลับทันที เพื่อให้แน่ใจว่าหมายเลขลำดับเริ่มต้นจะซิงโครไนซ์ได้อย่างน่าเชื่อถือ
แม้ว่าการจับมือแบบสี่ทิศทางยังสามารถซิงโครไนซ์หมายเลขลำดับเริ่มต้นของทั้งสองฝ่ายได้อย่างน่าเชื่อถือ แต่ขั้นตอนที่สองและสามสามารถรวมเป็นขั้นตอนเดียวได้ ซึ่งส่งผลให้เกิดการจับมือแบบสามทาง อย่างไรก็ตาม การจับมือทั้งสองครั้งสามารถรับประกันได้ว่าอีกฝ่ายจะได้รับหมายเลขลำดับเริ่มต้นของฝ่ายหนึ่งได้สำเร็จ แต่ไม่มีการรับประกันว่าจะสามารถยืนยันหมายเลขลำดับเริ่มต้นของทั้งสองฝ่ายได้ ดังนั้นการจับมือแบบสามทางจึงเป็นทางเลือกที่ดีที่สุดเพื่อให้มั่นใจในความเสถียรและความน่าเชื่อถือของการเชื่อมต่อ TCP
เหตุผลที่ 3: หลีกเลี่ยงการสิ้นเปลืองทรัพยากร
หากมีเพียง "การจับมือสองครั้ง" เมื่อคำขอ SYN ของไคลเอ็นต์ถูกบล็อกในเครือข่าย ไคลเอ็นต์จะไม่สามารถรับแพ็กเก็ต ACK ที่เซิร์ฟเวอร์ส่งได้ ดังนั้น SYN จะถูกส่งอีกครั้ง อย่างไรก็ตาม เนื่องจากไม่มีการจับมือกันครั้งที่สาม เซิร์ฟเวอร์จึงไม่สามารถระบุได้ว่าไคลเอ็นต์ได้รับการตอบรับ ACK เพื่อสร้างการเชื่อมต่อหรือไม่ ดังนั้น เซิร์ฟเวอร์จะสามารถสร้างการเชื่อมต่อได้ในเชิงรุกหลังจากได้รับคำขอ SYN แต่ละรายการเท่านั้น สิ่งนี้นำไปสู่สิ่งต่อไปนี้:
การสิ้นเปลืองทรัพยากร: หากคำขอ SYN ของลูกค้าถูกบล็อก ซึ่งส่งผลให้มีการส่งแพ็คเก็ต SYN หลายชุดซ้ำ เซิร์ฟเวอร์จะสร้างการเชื่อมต่อที่ไม่ถูกต้องซ้ำซ้อนหลายรายการหลังจากได้รับคำขอ สิ่งนี้นำไปสู่การสิ้นเปลืองทรัพยากรเซิร์ฟเวอร์โดยไม่จำเป็น
การเก็บรักษาข้อความ: เนื่องจากไม่มีการจับมือกันครั้งที่สาม เซิร์ฟเวอร์จึงไม่มีทางรู้ได้ว่าไคลเอ็นต์ได้รับการตอบรับ ACK อย่างถูกต้องเพื่อสร้างการเชื่อมต่อหรือไม่ ผลก็คือ หากข้อความติดอยู่ในเครือข่าย ไคลเอนต์จะส่งคำขอ SYN ซ้ำแล้วซ้ำเล่า ทำให้เซิร์ฟเวอร์สร้างการเชื่อมต่อใหม่อย่างต่อเนื่อง สิ่งนี้จะเพิ่มความแออัดและความล่าช้าของเครือข่าย และส่งผลเสียต่อประสิทธิภาพเครือข่ายโดยรวม
ดังนั้น เพื่อให้มั่นใจในความเสถียรและความน่าเชื่อถือของการเชื่อมต่อเครือข่าย TCP จะใช้การจับมือสามทางเพื่อสร้างการเชื่อมต่อเพื่อหลีกเลี่ยงไม่ให้เกิดปัญหาเหล่านี้
สรุป
ที่นายหน้าแพ็คเก็ตเครือข่ายการสร้างการเชื่อมต่อ TCP ทำได้ด้วยการจับมือแบบสามทาง ในระหว่างการจับมือแบบสามทาง ไคลเอนต์จะส่งแพ็กเก็ตที่มีแฟล็ก SYN ไปยังเซิร์ฟเวอร์ก่อน เพื่อระบุว่าต้องการสร้างการเชื่อมต่อ หลังจากได้รับคำขอจากไคลเอนต์ เซิร์ฟเวอร์จะตอบกลับแพ็กเก็ตที่มีแฟล็ก SYN และ ACK ไปยังไคลเอนต์ เพื่อระบุว่าคำขอการเชื่อมต่อได้รับการยอมรับ และส่งหมายเลขลำดับเริ่มต้นของตัวเอง สุดท้ายนี้ ไคลเอนต์จะตอบกลับด้วยค่าสถานะ ACK ไปยังเซิร์ฟเวอร์เพื่อระบุว่าการเชื่อมต่อได้สำเร็จแล้ว ดังนั้นทั้งสองฝ่ายจึงอยู่ในสถานะ ESTABLISHED และสามารถเริ่มส่งข้อมูลให้กันและกันได้
โดยทั่วไป กระบวนการจับมือสามทางสำหรับการสร้างการเชื่อมต่อ TCP ได้รับการออกแบบมาเพื่อให้มั่นใจในความเสถียรและความน่าเชื่อถือของการเชื่อมต่อ หลีกเลี่ยงความสับสนและการสิ้นเปลืองทรัพยากรจากการเชื่อมต่อในอดีต และให้แน่ใจว่าทั้งสองฝ่ายสามารถรับและส่งข้อมูลได้
เวลาโพสต์: Jan-08-2025