ปริศนาสำคัญของการเชื่อมต่อ TCP ของ Network Packet Broker: ไขความลับของความจำเป็นในการจับมือสามขั้นตอน (Triple Handshake)

การตั้งค่าการเชื่อมต่อ TCP
เมื่อเราท่องเว็บ ส่งอีเมล หรือเล่นเกมออนไลน์ เรามักไม่ได้คิดถึงการเชื่อมต่อเครือข่ายที่ซับซ้อนเบื้องหลัง แต่ขั้นตอนเล็กๆ เหล่านี้เองที่ทำให้การสื่อสารระหว่างเรากับเซิร์ฟเวอร์มีความเสถียร หนึ่งในขั้นตอนที่สำคัญที่สุดคือการตั้งค่าการเชื่อมต่อ TCP และหัวใจสำคัญของขั้นตอนนี้คือการจับมือสามขั้นตอน (three-way handshake)

บทความนี้จะกล่าวถึงหลักการ กระบวนการ และความสำคัญของการจับมือสามขั้นตอนโดยละเอียด เราจะอธิบายทีละขั้นตอนว่าทำไมการจับมือสามขั้นตอนจึงมีความจำเป็น วิธีการที่ช่วยให้การเชื่อมต่อมีความเสถียรและเชื่อถือได้ และความสำคัญของการถ่ายโอนข้อมูล ด้วยความเข้าใจที่ลึกซึ้งยิ่งขึ้นเกี่ยวกับการจับมือสามขั้นตอน เราจะเข้าใจกลไกพื้นฐานของการสื่อสารเครือข่ายได้ดีขึ้น และมองเห็นความน่าเชื่อถือของการเชื่อมต่อ TCP ได้ชัดเจนยิ่งขึ้น

กระบวนการจับมือสามทางและการเปลี่ยนสถานะของ TCP
TCP เป็นโปรโตคอลการขนส่งแบบเชื่อมต่อ (connection-oriented transport protocol) ซึ่งต้องมีการสร้างการเชื่อมต่อก่อนการส่งข้อมูล กระบวนการสร้างการเชื่อมต่อนี้ทำได้โดยการจับมือสามขั้นตอน (three-way handshake)

 การจับมือสามขั้นตอนของ TCP

มาดูรายละเอียดของแพ็กเก็ต TCP ที่ส่งในแต่ละการเชื่อมต่อกันดีกว่า

ในขั้นต้น ทั้งไคลเอนต์และเซิร์ฟเวอร์จะอยู่ในสถานะปิด (CLOSED) ก่อนอื่น เซิร์ฟเวอร์จะรอรับการเชื่อมต่อจากพอร์ตและอยู่ในสถานะฟัง (LISTEN) ซึ่งหมายความว่าเซิร์ฟเวอร์ต้องเริ่มต้นทำงานก่อน จากนั้น ไคลเอนต์จึงพร้อมที่จะเข้าถึงเว็บเพจ โดยต้องสร้างการเชื่อมต่อกับเซิร์ฟเวอร์ รูปแบบของแพ็กเก็ตการเชื่อมต่อครั้งแรกมีดังนี้:

 แพ็กเก็ต SYN

เมื่อไคลเอ็นต์เริ่มต้นการเชื่อมต่อ มันจะสร้างหมายเลขลำดับเริ่มต้นแบบสุ่ม (client_isn) และใส่ไว้ในฟิลด์ "หมายเลขลำดับ" ของส่วนหัว TCP ในขณะเดียวกัน ไคลเอ็นต์จะตั้งค่าตำแหน่งแฟล็ก SYN เป็น 1 เพื่อระบุว่าแพ็กเก็ตขาออกเป็นแพ็กเก็ต SYN ไคลเอ็นต์ระบุว่าต้องการสร้างการเชื่อมต่อกับเซิร์ฟเวอร์โดยการส่งแพ็กเก็ต SYN แรกไปยังเซิร์ฟเวอร์ แพ็กเก็ตนี้ไม่มีข้อมูลระดับแอปพลิเคชัน (นั่นคือ ข้อมูลที่ส่ง) ณ จุดนี้ สถานะของไคลเอ็นต์จะถูกทำเครื่องหมายเป็น SYN-SENT

แพ็กเก็ต SYN+ACK

เมื่อเซิร์ฟเวอร์ได้รับแพ็กเก็ต SYN จากไคลเอนต์ เซิร์ฟเวอร์จะสุ่มกำหนดหมายเลขลำดับของตัวเอง (server_isn) แล้วใส่หมายเลขนั้นลงในช่อง "หมายเลขลำดับ" ของส่วนหัว TCP จากนั้น เซิร์ฟเวอร์จะใส่ค่า client_isn + 1 ลงในช่อง "หมายเลขการรับทราบ" และตั้งค่าบิต SYN และ ACK เป็น 1 สุดท้าย เซิร์ฟเวอร์จะส่งแพ็กเก็ตไปยังไคลเอนต์ ซึ่งไม่มีข้อมูลระดับแอปพลิเคชัน (และไม่มีข้อมูลให้เซิร์ฟเวอร์ส่ง) ในขณะนี้ เซิร์ฟเวอร์อยู่ในสถานะ SYN-RCVD

แพ็กเก็ต ACK

เมื่อไคลเอ็นต์ได้รับแพ็กเก็ตจากเซิร์ฟเวอร์แล้ว ไคลเอ็นต์จะต้องดำเนินการปรับแต่งต่อไปนี้เพื่อตอบสนองต่อแพ็กเก็ตตอบกลับสุดท้าย: ขั้นแรก ไคลเอ็นต์จะตั้งค่าบิต ACK ของส่วนหัว TCP ของแพ็กเก็ตตอบกลับเป็น 1; ขั้นที่สอง ไคลเอ็นต์ป้อนค่า server_isn + 1 ในช่อง "ยืนยันหมายเลขคำตอบ"; สุดท้าย ไคลเอ็นต์ส่งแพ็กเก็ตไปยังเซิร์ฟเวอร์ แพ็กเก็ตนี้สามารถบรรจุข้อมูลจากไคลเอ็นต์ไปยังเซิร์ฟเวอร์ได้ เมื่อการดำเนินการเหล่านี้เสร็จสิ้น ไคลเอ็นต์จะเข้าสู่สถานะ ESTABLISHED

เมื่อเซิร์ฟเวอร์ได้รับแพ็กเก็ตตอบกลับจากไคลเอนต์แล้ว สถานะของเซิร์ฟเวอร์ก็จะเปลี่ยนเป็น ESTABLISHED เช่นกัน

ดังที่คุณเห็นจากกระบวนการข้างต้น เมื่อทำการจับมือสามขั้นตอน การจับมือขั้นตอนที่สามจะอนุญาตให้ส่งข้อมูลได้ แต่การจับมือสองขั้นตอนแรกจะไม่ได้รับอนุญาต นี่เป็นคำถามที่มักถูกถามในการสัมภาษณ์ เมื่อการจับมือสามขั้นตอนเสร็จสมบูรณ์ ทั้งสองฝ่ายจะเข้าสู่สถานะ ESTABLISHED ซึ่งบ่งชี้ว่าการเชื่อมต่อได้รับการสร้างขึ้นอย่างสำเร็จแล้ว ณ จุดนี้ ไคลเอนต์และเซิร์ฟเวอร์สามารถเริ่มส่งข้อมูลถึงกันได้

ทำไมต้องจับมือสามครั้ง ไม่ใช่สองครั้ง แต่สี่ครั้ง?
คำตอบทั่วไปคือ "เพราะการจับมือสามทางรับประกันความสามารถในการรับและส่ง" คำตอบนี้ถูกต้อง แต่เป็นเพียงเหตุผลผิวเผิน ไม่ใช่เหตุผลหลัก ในส่วนต่อไปนี้ ผมจะวิเคราะห์เหตุผลของการจับมือสามทางจากสามแง่มุม เพื่อให้เราเข้าใจประเด็นนี้อย่างลึกซึ้งยิ่งขึ้น

การจับมือสามขั้นตอนสามารถหลีกเลี่ยงการเริ่มต้นการเชื่อมต่อซ้ำซ้อนในอดีตได้อย่างมีประสิทธิภาพ (ซึ่งเป็นเหตุผลหลัก)
การจับมือสามทางรับประกันว่าทั้งสองฝ่ายได้รับหมายเลขลำดับเริ่มต้นที่เชื่อถือได้แล้ว
การจับมือสามฝ่ายช่วยหลีกเลี่ยงการสิ้นเปลืองทรัพยากร

เหตุผลที่ 1: หลีกเลี่ยงการเชื่อมข้อมูลซ้ำซ้อนในอดีต
โดยสรุปแล้ว เหตุผลหลักของการจับมือสามขั้นตอน (three-way handshake) คือเพื่อหลีกเลี่ยงความสับสนที่เกิดจากการเริ่มต้นการเชื่อมต่อซ้ำซ้อนเก่า ในสภาพแวดล้อมเครือข่ายที่ซับซ้อน การส่งแพ็กเก็ตข้อมูลไม่ได้ถูกส่งไปยังโฮสต์ปลายทางตามเวลาที่กำหนดเสมอไป และแพ็กเก็ตข้อมูลเก่าอาจมาถึงโฮสต์ปลายทางก่อนเนื่องจากความแออัดของเครือข่ายและเหตุผลอื่นๆ เพื่อหลีกเลี่ยงปัญหานี้ TCP จึงใช้การจับมือสามขั้นตอนในการสร้างการเชื่อมต่อ

การจับมือสามทางช่วยหลีกเลี่ยงการเชื่อมต่อที่ซ้ำซ้อนในอดีต

เมื่อไคลเอ็นต์ส่งแพ็กเก็ตการสร้างการเชื่อมต่อ SYN หลายแพ็กเก็ตติดต่อกัน ในสถานการณ์เช่นความแออัดของเครือข่าย อาจเกิดสิ่งต่อไปนี้:

1. แพ็กเก็ต SYN เก่าจะมาถึงเซิร์ฟเวอร์ก่อนแพ็กเก็ต SYN ล่าสุด
2. หลังจากได้รับแพ็กเก็ต SYN เก่าแล้ว เซิร์ฟเวอร์จะส่งแพ็กเก็ต SYN + ACK กลับไปยังไคลเอนต์
3. เมื่อไคลเอ็นต์ได้รับแพ็กเก็ต SYN + ACK มันจะพิจารณาว่าการเชื่อมต่อดังกล่าวเป็นการเชื่อมต่อในอดีต (หมายเลขลำดับหมดอายุหรือหมดเวลา) ตามบริบทของตนเอง จากนั้นจึงส่งแพ็กเก็ต RST ไปยังเซิร์ฟเวอร์เพื่อยกเลิกการเชื่อมต่อ

การเชื่อมต่อแบบสองขั้นตอน (two-way handshake) ไม่สามารถระบุได้ว่าการเชื่อมต่อปัจจุบันเป็นการเชื่อมต่อในอดีตหรือไม่ แต่การเชื่อมต่อแบบสามขั้นตอน (three-way 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 จึงใช้การจับมือสามขั้นตอน (three-way handshake) ในการสร้างการเชื่อมต่อเพื่อหลีกเลี่ยงการเกิดปัญหาเหล่านี้

สรุป
เดอะตัวกลางส่งแพ็กเก็ตเครือข่ายการสร้างการเชื่อมต่อ TCP ทำได้โดยการจับมือสามขั้นตอน (three-way handshake) ในระหว่างการจับมือสามขั้นตอน ขั้นแรก ไคลเอนต์จะส่งแพ็กเก็ตที่มีแฟล็ก SYN ไปยังเซิร์ฟเวอร์ เพื่อแสดงว่าต้องการสร้างการเชื่อมต่อ หลังจากได้รับคำขอจากไคลเอนต์แล้ว เซิร์ฟเวอร์จะตอบกลับแพ็กเก็ตที่มีแฟล็ก SYN และ ACK ไปยังไคลเอนต์ เพื่อแสดงว่ายอมรับคำขอเชื่อมต่อ และส่งหมายเลขลำดับเริ่มต้นของตนเองไปด้วย สุดท้าย ไคลเอนต์จะตอบกลับด้วยแฟล็ก ACK ไปยังเซิร์ฟเวอร์เพื่อแสดงว่าการเชื่อมต่อได้ถูกสร้างขึ้นสำเร็จแล้ว ดังนั้น ทั้งสองฝ่ายจึงอยู่ในสถานะ ESTABLISHED และสามารถเริ่มส่งข้อมูลระหว่างกันได้

โดยทั่วไป กระบวนการจับมือสามทางสำหรับการสร้างการเชื่อมต่อ TCP ถูกออกแบบมาเพื่อให้มั่นใจถึงความเสถียรและความน่าเชื่อถือของการเชื่อมต่อ หลีกเลี่ยงความสับสนและการสิ้นเปลืองทรัพยากรจากการเชื่อมต่อในอดีต และเพื่อให้มั่นใจว่าทั้งสองฝ่ายสามารถรับและส่งข้อมูลได้


วันที่โพสต์: 8 มกราคม 2568