TCP Three-Way Handshake - แฟล็ก SYN และ ACK

ส่วนหัว UDP จะมีความยาว 64 บิตเสมอ ฟิลด์ที่กำหนดในส่วน UDP (ดูรูป) มีดังต่อไปนี้:
1. พอร์ตต้นทาง: หมายเลขพอร์ตต้นทาง (16 บิต)
2. พอร์ตปลายทาง: หมายเลขพอร์ตปลายทาง (16 บิต)
3. ความยาวของข้อความ: ความยาวส่วนหัว UDP และ ข้อมูล UDP(16 บิต)
4. เช็คซัม: เช็คซัมที่คำนวณได้ของส่วนหัวและฟิลด์ข้อมูล (16 บิต)
5. ข้อมูล: ข้อมูลโปรโตคอลชั้นบน (ULP) (ความยาวผันแปร)
ตัวอย่างโปรโตคอลที่ใช้ UDP: TFTP, SNMP, ไฟล์เครือข่ายระบบ (NFS) และโดเมน ระบบชื่อ(ดีเอ็นเอส)

ส่วนหัว TCP ประกอบด้วยข้อมูลที่ถูกกำหนดไว้ โปรโตคอล TCP- ใน ส่วนนี้มีการอธิบายส่วนประกอบของส่วนหัว TCP

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

พอร์ตต้นทาง: หมายเลขพอร์ตต้นทาง (16 บิต)

พอร์ตปลายทาง: หมายเลขพอร์ตปลายทาง (16 บิต)

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

หมายเลขรับทราบ: ออคเต็ตถัดไปที่คาดไว้
TCP (32 บิต)

ความยาวส่วนหัว: จำนวนคำ 32 บิตในส่วนหัว (4 บิต)

สงวนไว้: ตั้งค่าเป็น 0 (3 บิต)

บิตควบคุม: ฟังก์ชั่นควบคุม เช่น การตั้งค่า
โอเวอร์โหลดและการยกเลิกเซสชัน (9 บิต) นิดเดียวที่มีความพิเศษ
ค่าที่มักคิดว่าเป็นธง

หน้าต่าง: จำนวนออคเต็ตที่อุปกรณ์ยินดียอมรับ (16 บิต)

เช็คซัม: เช็คซัมที่คำนวณได้ของส่วนหัวและ
ข้อมูล (16 บิต)

ด่วน: ระบุจุดสิ้นสุดของข้อมูลเร่งด่วน (16 บิต)

ตัวเลือก: ปัจจุบันมีการกำหนดตัวเลือกเดียว - ขนาดสูงสุด
ส่วน TCP (0 หรือ 32 บิต)

ข้อมูล: ข้อมูลโปรโตคอลชั้นบน (ULP)
(ความยาวแปรผัน)

0 - 3

4 - 9

10 - 15

16 - 31

พอร์ตต้นทาง

ท่าเรือปลายทาง,พอร์ตปลายทาง

หมายเลขซีเรียลหมายเลขลำดับ (SN)

หมายเลขยืนยัน

ความยาวส่วนหัว

ที่สงวนไว้

ธง

ขนาดหน้าต่าง

เช็คซัม

ตัวบ่งชี้ความสำคัญ

ตัวเลือก (เป็นทางเลือก แต่ใช้เกือบทุกครั้ง)

160/192+

ข้อมูล

พอร์ตต้นทาง พอร์ตปลายทาง

ฟิลด์ 16 บิตเหล่านี้ประกอบด้วยตัวเลขพอร์ต - ตัวเลขที่กำหนดโดยรายการพิเศษ .

พอร์ตต้นทาง ระบุแอปพลิเคชันไคลเอ็นต์ที่ใช้ส่งแพ็กเก็ต ข้อมูลการตอบสนองจะถูกส่งไปยังไคลเอนต์ตามหมายเลขนี้

ท่าเรือปลายทาง ระบุพอร์ตที่แพ็กเก็ตถูกส่งไป

หมายเลขซีเรียล

หมายเลขลำดับมีจุดประสงค์สองประการ:

  1. หากตั้งค่าสถานะ SYN นี่คือหมายเลขลำดับเริ่มต้น - ISN (หมายเลขลำดับเริ่มต้น) และไบต์แรกของข้อมูลที่จะถ่ายโอนไปยัง แพ็คเกจถัดไปจะมีตัวเลขเท่ากับ ISN + 1
  2. มิฉะนั้น หากไม่ได้ตั้งค่า SYN ไบต์แรกของข้อมูลที่ส่งในแพ็กเก็ตที่กำหนดจะมีหมายเลขลำดับนี้

เนื่องจากโดยทั่วไปสตรีม TCP สามารถมีความยาวได้มากกว่าจำนวนสถานะที่แตกต่างกันของฟิลด์นี้ การดำเนินการทั้งหมดที่มีหมายเลขลำดับจะต้องดำเนินการแบบโมดูโล 2 32 - นี่เป็นการจำกัดการใช้งาน TCP ในทางปฏิบัติ ถ้าโอนเร็ว ระบบการสื่อสารเป็นเช่นนั้นในระหว่าง MSL (อายุการใช้งานเซ็กเมนต์สูงสุด) หมายเลขลำดับล้น จากนั้นสองเซ็กเมนต์ที่มีหมายเลขเดียวกันอาจปรากฏในเครือข่ายที่เกี่ยวข้องกับ ส่วนต่างๆสตรีมและผู้รับจะได้รับข้อมูลที่ไม่ถูกต้อง

เอ็น หมายเลขยืนยัน

หมายเลขรับทราบ (ACK SN)(32 บิต) - หากตั้งค่าบิต ACK ฟิลด์นี้จะมีหมายเลขลำดับของออคเต็ตที่ผู้ส่งในส่วนนี้ต้องการรับ ซึ่งหมายความว่าได้รับออคเต็ตก่อนหน้าทั้งหมด (หมายเลข ISN+1 ถึง ACK-1 ด้วย) ได้รับเรียบร้อยแล้ว

ดี บรรทัดส่วนหัว (ออฟเซ็ตข้อมูล)

ฟิลด์นี้ระบุขนาดของส่วนหัวของแพ็กเก็ต TCP ในคำขนาด 4 ไบต์ (4-octet) ขนาดขั้นต่ำคือ 5 คำ และสูงสุดคือ 15 ซึ่งก็คือ 20 และ 60 ไบต์ ตามลำดับ ออฟเซ็ตจะคำนวณจากจุดเริ่มต้นของส่วนหัว TCP

3 จองแล้ว

สงวนไว้ (6 บิต) เพื่อใช้ในอนาคตและต้องตั้งค่าเป็นศูนย์ ในจำนวนนี้มีสอง (ที่ 5 และ 6) ถูกกำหนดไว้แล้ว:

  • CWR (ลดความแออัดของหน้าต่าง) - ฟิลด์ลดความแออัดของหน้าต่าง - ตั้งค่าสถานะโดยผู้ส่งเพื่อระบุว่าได้รับแพ็กเก็ตด้วยการตั้งค่าสถานะ ECE (RFC 3168)
  • ECE (ECN-Echo) - ฟิลด์ ECN Echo - ระบุว่าโหนดนี้สามารถรองรับ ECN (การแจ้งเตือนความแออัดอย่างชัดเจน) และเพื่อแจ้งให้ผู้ส่งทราบเกี่ยวกับความแออัดของเครือข่าย (RFC 3168)

เอฟ ล่าช้า (บิตควบคุม)

ฟิลด์นี้มีแฟล็ก 6 บิต:

  • URG - ฟิลด์ “ดัชนีความสำคัญ”มีส่วนร่วม (อังกฤษ) ช่องตัวชี้ด่วนมีความสำคัญ)
  • อ๊าก - สนาม “หมายเลขยืนยัน”มีส่วนร่วม (อังกฤษ) ช่องรับทราบมีความสำคัญ)
  • PSH - (ฟังก์ชัน Push ภาษาอังกฤษ) สั่งให้ผู้รับส่งข้อมูลที่สะสมในบัฟเฟอร์การรับไปยังแอปพลิเคชันของผู้ใช้
  • RST - ตัดการเชื่อมต่อ, รีเซ็ตบัฟเฟอร์ (การล้างบัฟเฟอร์) (อังกฤษ รีเซ็ตการเชื่อมต่อ)
  • SYN - ซิงโครไนซ์หมายเลขลำดับ
  • FIN (ตอนจบภาษาอังกฤษ บิต) - เมื่อตั้งค่าสถานะ บ่งชี้ว่าการเชื่อมต่อเสร็จสมบูรณ์ (ภาษาอังกฤษ. บิต FIN ใช้สำหรับยุติการเชื่อมต่อ).

ขนาดหน้าต่าง

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

ถึง เช็คซัม

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

คุณ ตัวบ่งชี้ความสำคัญ

ค่า 16 บิตของออฟเซ็ตบวกจากหมายเลขลำดับในส่วนนี้ ฟิลด์นี้ระบุหมายเลขลำดับออคเต็ตที่สิ้นสุดข้อมูลเร่งด่วน ช่องนี้จะนำมาพิจารณาเฉพาะแพ็กเก็ตที่มีการตั้งค่าสถานะ URG เท่านั้น ใช้สำหรับข้อมูลนอกแบนด์ .

เกี่ยวกับตัวเลือก

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

กลไกของโปรโตคอล

ไม่เหมือน ทางเลือกแบบดั้งเดิม- UDP ซึ่งสามารถเริ่มส่งแพ็กเก็ตได้ทันที TCP จะสร้างการเชื่อมต่อที่ต้องสร้างก่อนที่จะส่งข้อมูล การเชื่อมต่อทีพีพีสามารถแบ่งออกเป็น 3 ขั้นตอน:

  • กำลังสร้างการเชื่อมต่อ
  • การถ่ายโอนข้อมูล
  • การสิ้นสุดการเชื่อมต่อ

กับ สถานะเซสชัน TCP

แผนภาพสถานะ TCP แบบง่าย รายละเอียดเพิ่มเติมในไดอะแกรม TCP EFSM (เป็นภาษาอังกฤษ)

สถานะเซสชัน TCP

ปิด

สถานะเริ่มต้นของโหนด จริงๆแล้วเป็นเรื่องสมมุติ

ฟัง

เซิร์ฟเวอร์รอคำขอการเชื่อมต่อจากไคลเอนต์

SYN-ส่ง

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

ได้รับ SYN แล้ว

เซิร์ฟเวอร์ได้รับคำขอเชื่อมต่อ ส่งคำขอตอบกลับ และกำลังรอการยืนยัน

ที่จัดตั้งขึ้น

สร้างการเชื่อมต่อแล้ว กำลังถ่ายโอนข้อมูล

FIN-รอ-1

ฝ่ายใดฝ่ายหนึ่ง (เรียกว่าโหนด 1) เสร็จสิ้นการเชื่อมต่อโดยการส่งส่วนที่มีธง FIN

ปิดรอ

อีกด้านหนึ่ง (โหนด-2) เข้าสู่สถานะนี้โดยการส่งส่วน ACK ตามลำดับ และดำเนินการส่งข้อมูลแบบทางเดียวต่อไป

FIN-รอ-2

Node-1 ได้รับ ACK อ่านต่อและรอรับเซ็กเมนต์ที่มีแฟล็ก FIN

สุดท้าย-ACK

Node-2 สิ้นสุดการส่งและส่งเซ็กเมนต์ด้วยแฟล็ก FIN

เวลารอ

โหนด-1 ได้รับเซ็กเมนต์ที่มีแฟล็ก FIN ส่งเซ็กเมนต์ที่มีแฟล็ก ACK และรอ 2*MSL วินาทีก่อนที่จะปิดการเชื่อมต่อในที่สุด

ปิด

ทั้งสองฝ่ายเริ่มต้นการปิดการเชื่อมต่อในเวลาเดียวกัน: หลังจากส่งเซ็กเมนต์ที่มีธง FIN แล้ว โหนด-1 ยังได้รับเซ็กเมนต์ FIN ส่ง ACK และรอเซ็กเมนต์ ACK (รับทราบคำขอตัดการเชื่อมต่อ)

คุณ สร้างการเชื่อมต่อ

กระบวนการเริ่มต้นเซสชัน TCP (เรียกอีกอย่างว่า "การจับมือกัน" (ภาษาอังกฤษ การจับมือกัน )) ประกอบด้วย 3 ขั้นตอน

1. ไคลเอนต์ซึ่งตั้งใจจะสร้างการเชื่อมต่อจะส่งเซ็กเมนต์ไปยังเซิร์ฟเวอร์พร้อมหมายเลขลำดับและ ธงซิน.

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

2. หากไคลเอนต์ได้รับเซ็กเมนต์ที่มีแฟล็ก SYN ก็จะจดจำหมายเลขลำดับและส่งเซ็กเมนต์ที่มีแฟล็ก ACK

  • หากได้รับค่าสถานะ ACK ในเวลาเดียวกัน (ซึ่งมักจะเกิดขึ้น) จากนั้นจะเข้าสู่สถานะ ESTABLISHED
  • หากไคลเอ็นต์ได้รับเซ็กเมนต์ที่มีแฟล็ก RST ไคลเอ็นต์จะหยุดพยายามเชื่อมต่อ
  • หากไคลเอนต์ไม่ได้รับการตอบกลับภายใน 10 วินาที จะทำขั้นตอนการเชื่อมต่อซ้ำอีกครั้ง

3. หากเซิร์ฟเวอร์ในสถานะ SYN-RECEIVED ได้รับเซ็กเมนต์ที่มีแฟล็ก ACK จากนั้นเซิร์ฟเวอร์จะเข้าสู่สถานะ ESTABLISHED

  • มิฉะนั้น หลังจากหมดเวลา จะปิดซ็อกเก็ตและเข้าสู่สถานะปิด

กระบวนการนี้เรียกว่า "การจับคู่สามขั้นตอน" (ภาษาอังกฤษ การจับมือกันสามทาง ) เนื่องจากแม้ว่าจะเป็นไปได้ที่จะสร้างการเชื่อมต่อกับก็ตาม ใช้สี่เซ็กเมนต์ (SYN ไปยังเซิร์ฟเวอร์, ACK ไปยังไคลเอนต์, SYN ไปยังไคลเอนต์, ACK ไปยังเซิร์ฟเวอร์) ในทางปฏิบัติ มีการใช้สามเซ็กเมนต์เพื่อประหยัดเวลา

ตัวอย่างการอนุมัติพื้นฐาน 3 ขั้นตอน:

TCP A TCP B

1. ปิดการฟัง

2. ซิน-ส่ง --> -> ได้รับ SYN แล้ว

3. ก่อตั้งแล้ว<-- <-- SYN-RECEIVED

4. ก่อตั้ง --> -->ก่อตั้งแล้ว

5. ก่อตั้งแล้ว<-- <-- ESTABLISHED

ในบรรทัดที่ 2 TCP A เริ่มส่งเซ็กเมนต์ SYN ที่ระบุการใช้หมายเลขลำดับ เริ่มต้นด้วย 100 ในบรรทัดที่ 3 TCP B จะส่ง SYN และการตอบรับสำหรับ SYN ที่ได้รับไปยัง TCP A ควรสังเกตว่าฟิลด์การตอบรับ ระบุว่า TCP B กำลังรอหมายเลขลำดับที่จะได้รับ 101 ยืนยันหมายเลข SYN 100

ในบรรทัดที่ 4 TCP A ตอบสนองด้วยเซ็กเมนต์ว่างด้วย ACK สำหรับเซ็กเมนต์ SYN จาก TCP B ในบรรทัดที่ 5 TCP B ส่งข้อมูลบางส่วน โปรดทราบว่าหมายเลขการตอบรับเซ็กเมนต์ในบรรทัดที่ 5 (ACK=101) จะเหมือนกับหมายเลขลำดับในบรรทัดที่ 4 (SEQ=101) เนื่องจาก ACK ไม่ได้ใช้พื้นที่หมายเลขลำดับ (หากเสร็จสิ้น คุณจะต้องรับทราบการตอบรับ - อ๊าก สำหรับ อ๊าก)อัลกอริทึมของ Nagle และการเริ่มช้า

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

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

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

ซี การสิ้นสุดการเชื่อมต่อ

การยกเลิกการเชื่อมต่อสามารถพิจารณาได้ในสามขั้นตอน:

  1. การส่งแฟล็ก FIN ไปยังเซิร์ฟเวอร์จากไคลเอนต์เพื่อยุติการเชื่อมต่อ
  2. เซิร์ฟเวอร์ส่งแฟล็กการตอบสนองของไคลเอ็นต์ ACK, FIN เพื่อระบุว่าการเชื่อมต่อถูกปิด
  3. หลังจากได้รับค่าสถานะเหล่านี้ ไคลเอนต์จะปิดการเชื่อมต่อ และส่ง ACK ไปยังเซิร์ฟเวอร์เพื่อยืนยันว่า การเชื่อมต่อถูกปิด

การใช้โปรแกรมที่วิเคราะห์การรับส่งข้อมูลและโปรโตคอลที่ใช้ - Wireshark คุณสามารถสังเกตการทำงานของการจับมือ TCP สามขั้นตอน:


ขั้นตอนที่ 1

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

รูปภาพนี้แสดงให้เห็นว่าเอาต์พุตของตัววิเคราะห์โปรโตคอลแสดงแฟล็กควบคุม SYN และหมายเลขลำดับสัมพัทธ์อย่างไร

มีการตั้งค่าสถานะควบคุม SYN และหมายเลขลำดับสัมพัทธ์คือ 0 แม้ว่ากราฟตัววิเคราะห์โปรโตคอลจะระบุค่าสัมพัทธ์สำหรับหมายเลขลำดับและหมายเลขตอบรับ แต่ค่าจริงจะเป็นตัวเลขไบนารี 32 บิต เราสามารถระบุจำนวนจริงที่ส่งในส่วนหัวของเซ็กเมนต์ได้โดยตรวจสอบพื้นที่ "Packet Bytes" ที่นี่คุณจะเห็นสี่ไบต์ที่แสดงอยู่ เลขฐานสิบหกรูปร่าง.

ขั้นตอนที่ 2

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

โปรโตคอล TCP/IP ถูกสร้างขึ้นครั้งแรกในต้นปี 1970 และถูกใช้เพื่อสร้าง ARPANET เทคโนโลยีนี้ได้รับการพัฒนาโดยเป็นส่วนหนึ่งของโครงการวิจัยที่มีวัตถุประสงค์เพื่อศึกษาความเป็นไปได้ในการรวมคอมพิวเตอร์ภายในเครือข่ายอินเทอร์เน็ตท้องถิ่นหรือเสมือนเดียวกัน

การสร้างการเชื่อมต่อใน TCP ทำได้โดยใช้โปรแกรมไคลเอนต์พิเศษ เช่น เบราว์เซอร์ โปรแกรมอีเมล หรือไคลเอนต์การส่งข้อความ

โครงสร้าง TCP

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

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

การส่งข้อมูลผ่าน TCP

หลังจากสร้างการเชื่อมต่อแล้ว TCP จะส่งข้อมูลตามเส้นทางที่สร้างขึ้นตามที่อยู่ IP ของผู้ส่งและผู้รับข้อมูล ที่อยู่ IP คือตัวระบุเฉพาะของอุปกรณ์เครือข่ายแต่ละเครื่องบนอินเทอร์เน็ต ดังนั้นแพ็กเก็ตที่ส่งผ่านอุโมงค์ที่สร้างขึ้นจะไม่สูญหายหรือส่งผิดพลาดไปยังผู้ใช้รายอื่น

ในระดับทางกายภาพของการส่งข้อมูล ข้อมูลอยู่ในรูปแบบของความถี่ แอมพลิจูด และรูปแบบสัญญาณอื่น ๆ ซึ่งได้รับการประมวลผลโดยการ์ดเครือข่ายของผู้รับแล้ว

โปรโตคอลแชนเนลมีหน้าที่รับผิดชอบในการประมวลผลข้อมูลโดยคอมพิวเตอร์และส่งไปยังส่วนประกอบอื่น ๆ เช่น Ethernet, ATM, SLIP, IEEE 802.11 ช่องทางเหล่านี้ไม่เพียงแต่ให้การส่งข้อมูลเท่านั้น แต่ยังเป็นรูปแบบการส่งข้อมูลไปยังผู้รับอีกด้วย ดังนั้นในเครือข่าย IEEE 802.11 ข้อมูลจะถูกส่งโดยใช้สัญญาณวิทยุไร้สาย ในกรณีนี้สัญญาณจะมาจากการ์ดเครือข่ายของคอมพิวเตอร์ซึ่งมีรหัส MAC ของตัวเองด้วย ในกรณีของอีเธอร์เน็ต การส่งข้อมูลทั้งหมดจะดำเนินการโดยใช้การเชื่อมต่อสายเคเบิล

วิดีโอในหัวข้อ

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

เครือข่ายทั่วโลก (GCN) คือเครือข่ายที่ประกอบด้วยคอมพิวเตอร์ที่ครอบคลุมพื้นที่อันกว้างใหญ่พร้อมระบบคอมพิวเตอร์จำนวนไม่จำกัดที่รวมอยู่ในเครือข่ายนี้ เงื่อนไขหลักสำหรับการทำงานของเครือข่ายดังกล่าวคือการส่งข้อมูลผ่านเครือข่ายทันที โดยไม่คำนึงถึงระยะห่างของคอมพิวเตอร์ที่ส่งและรับ

เครือข่ายทั่วโลกแตกต่างจากเครือข่ายท้องถิ่น ประการแรกคือ มีอัตราการถ่ายโอนข้อมูลที่ต่ำกว่า เครือข่ายทั่วโลกทำงานผ่าน TCP/IP, MPLS, ATM และโปรโตคอลอื่นๆ สิ่งที่มีชื่อเสียงที่สุดคือโปรโตคอล TCP/IP ซึ่งรวมถึงโปรโตคอลย่อยในระดับที่แตกต่างกัน: แอปพลิเคชัน การขนส่ง เครือข่าย กายภาพ และช่องทาง

ในระดับแอปพลิเคชัน โปรแกรมส่วนใหญ่ทำงานโดยมีโปรโตคอลของตัวเองซึ่งผู้ใช้พีซีทั่วไปรู้จักอย่างกว้างขวาง (HTTP, WWW, FTP ฯลฯ ) โปรโตคอลเหล่านี้จัดให้มีการแสดงภาพและการแสดงข้อมูลที่ผู้ใช้ต้องการ

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

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

เลเยอร์ฟิสิคัลและลิงก์มีหน้าที่กำหนดเงื่อนไขและวิธีการส่งข้อมูล

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

วิดีโอในหัวข้อ

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

การเชื่อมต่ออินเทอร์เน็ตถูกสร้างขึ้นโดยใช้กลุ่มตัวเลข 4 ค่า คั่นด้วยสัญลักษณ์ “” และเรียกที่อยู่ IP ชื่อเชิงสัญลักษณ์ของชื่อโดเมนที่ซับซ้อนเป็นบริการที่ออกแบบมาเพื่อให้ง่ายต่อการค้นหาที่อยู่ IP ที่ต้องการบนเครือข่าย ตัวบ่งชี้ทางเทคนิคของชื่อโดเมนคือ “” ในที่อยู่อีเมลของผู้ใช้ ดังนั้นในที่อยู่ google.com ชื่อโดเมนจะเป็น com ชื่อไม่สามารถให้การเข้าถึงทรัพยากรอินเทอร์เน็ตที่จำเป็นได้ ขั้นตอนการใช้ชื่อช่วยจำประกอบด้วยสองขั้นตอน: - ที่อยู่ IP ตามชื่อในไฟล์โฮสต์ที่มีตารางการติดต่อระหว่างที่อยู่ IP และชื่อคอมพิวเตอร์ - สร้างการเชื่อมต่อกับทรัพยากรเว็บระยะไกลที่ที่อยู่ IP หลัก งานของบริการ DNS คือการได้รับที่อยู่ IP สำหรับสร้างการเชื่อมต่อ ซึ่งทำให้บริการนี้สนับสนุนโปรโตคอล TCP/IP สัญลักษณ์ "" เป็นตัวคั่นชื่อโดเมน แม้ว่าในทางปฏิบัติมักจะใช้เพื่ออ้างถึงโดเมนรากที่ไม่มีตัวระบุของตัวเอง รูท - ชุดโฮสต์อินเทอร์เน็ตทั้งหมด - แบ่งออกเป็น: - ระดับแรก - gov, edu, com, net; - โดเมนระดับชาติ - สหราชอาณาจักร, jp, ch ฯลฯ - โดเมนระดับภูมิภาค - msk; ขององค์กร การอนุรักษ์โครงสร้างต้นไม้ที่คุ้นเคยของชื่อโดเมนนำไปสู่การใช้คำศัพท์ที่กำหนดไว้ - รูท, โหนดต้นไม้, ใบไม้ คำว่า "โฮสต์" ในลำดับชั้นนี้ถูกกำหนดให้กับลีฟที่ไม่มีโหนดเดียวอยู่ข้างใต้ ชื่อโฮสต์แบบเต็มจะกลายเป็นรายการตามลำดับของโหนดกลางทั้งหมดระหว่างรูทและลีฟ โดยคั่นด้วยอักขระ "" จากซ้ายไปขวา: ivan.net.abcd.ru โดยที่ ru คือรากของต้นไม้ abcd คือชื่อขององค์กร ivan คือใบไม้ของต้นไม้ (โฮสต์)

วิดีโอในหัวข้อ

แหล่งที่มา:

  • ระบบชื่อโดเมนอินเทอร์เน็ตในปี 2561

ฉันชอบบทความทั้งชุดมากและฉันก็อยากลองเป็นนักแปลด้วยตัวเองมาโดยตลอด บางทีบทความนี้อาจดูเหมือนชัดเจนเกินไปสำหรับนักพัฒนาที่มีประสบการณ์ แต่สำหรับฉันแล้วดูเหมือนว่ามันจะมีประโยชน์ในทุกกรณี

สวัสดี ฉันชื่อ Glenn Fiedler ยินดีต้อนรับคุณสู่บทความแรกในหนังสือออนไลน์ของฉัน Network Programming for Game Developers

ในบทความนี้ เราจะเริ่มต้นด้วยลักษณะพื้นฐานที่สุดของการเขียนโปรแกรมเครือข่าย - การรับและส่งข้อมูลผ่านเครือข่าย การรับและส่งข้อมูลเป็นส่วนหลักและง่ายที่สุดของงานทั้งหมดที่โปรแกรมเมอร์เครือข่ายทำ แต่มักจะเป็นเรื่องยากที่จะพิจารณาว่าควรใช้วิธีใดดีที่สุด ให้ความสนใจกับส่วนนี้ให้เพียงพอ - หากคุณหลงเหลือความเข้าใจผิด อาจส่งผลร้ายแรงต่อเกมที่มีผู้เล่นหลายคนของคุณในภายหลัง!

คุณคงเคยได้ยินบางอย่างเกี่ยวกับซ็อกเก็ตมาบ้างแล้ว และคุณอาจรู้ว่าซ็อกเก็ตมีสองประเภทหลัก - TCP และ UDP สิ่งแรกที่คุณต้องตัดสินใจเมื่อพัฒนาเกมที่มีผู้เล่นหลายคนคือซ็อกเก็ตประเภทใดที่จะใช้ - TCP, UDP หรือทั้งสองอย่าง

การเลือกประเภทซ็อกเก็ตขึ้นอยู่กับประเภทของเกมที่คุณกำลังพัฒนา สำหรับบทความชุดนี้ ฉันจะถือว่าคุณกำลังเขียนเกมแอคชั่น เช่น Halo, Battlefield 1942, Quake, Unreal, CounterStrike, Team Fortress ฯลฯ

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

TCP ย่อมาจาก "โปรโตคอลควบคุมการส่งสัญญาณ" และ IP ย่อมาจาก "โปรโตคอลอินเทอร์เน็ต" สิ่งเหล่านี้ร่วมกันสนับสนุนเกือบทุกสิ่งที่คุณทำทางออนไลน์ ตั้งแต่การท่องเว็บไปจนถึง IRC และการสื่อสารทางอีเมล ทั้งหมดนี้ทำงานบน TCP/IP

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

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

อีกครั้งหนึ่ง - ทุกอย่างง่ายดายเหมือนการเขียนหรืออ่านจากไฟล์ตามปกติ ชั้นประถม วัตสัน!

แต่ความสะดวกในการใช้งานนี้แตกต่างอย่างสิ้นเชิงจากสิ่งที่เกิดขึ้นจริง "ใต้ฝากระโปรง" ในระดับที่ต่ำกว่า - ระดับโปรโตคอล IP

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

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

จะเป็นอย่างไรหากเราต้องการถ่ายโอนข้อมูลระหว่างคอมพิวเตอร์ที่ไม่ได้อยู่ในรูปแบบการอ่าน/เขียนไฟล์ แต่โดยการส่งและรับแพ็กเก็ตเดี่ยวโดยตรง?

เราสามารถทำได้โดยใช้ UDP UDP ย่อมาจาก “user datagram protocol” และทำงานบน IP (เช่น TCP) แต่แทนที่จะเพิ่มฟังก์ชันการทำงานมากมาย กลับเป็นเพียงส่วนเสริมเล็กๆ ของ IP

เมื่อใช้ UDP เราสามารถส่งแพ็กเก็ตไปยังที่อยู่ IP เฉพาะ (เช่น 112.140.20.10) และพอร์ต (เช่น 52423) และมันจะถูกส่งจากคอมพิวเตอร์หนึ่งไปอีกเครื่องหนึ่งจนกว่าจะถึงปลายทาง (หรือสูญหายไปตาม ทาง).

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

โปรโตคอล UDP ไม่รับประกันการส่งข้อมูล ในทางปฏิบัติแพ็กเก็ตส่วนใหญ่แน่นอนว่ามาถึงแต่ก็มักจะสูญเสียประมาณ 1-5% และบางครั้งก็มีช่วงเวลาที่แพ็กเก็ตมาไม่ถึงเลย (โปรดจำไว้ว่าระหว่างผู้ส่งและผู้รับอาจมี คอมพิวเตอร์หลายพันเครื่อง ซึ่งเครื่องใดเครื่องหนึ่งอาจล้มเหลวหรือพังได้)

นอกจากนี้ UDP ยังไม่รับประกันลำดับในการจัดส่งแพ็กเก็ต คุณสามารถส่งห้าแพ็คเก็ตตามลำดับ - 1, 2, 3, 4, 5 - แต่สามารถส่งในลำดับที่แตกต่างไปจากเดิมอย่างสิ้นเชิง - เช่น 3, 1, 2, 5, 4 อีกครั้ง ในทางปฏิบัติ พวกเขามักจะมีโอกาสมากที่สุด มาถึงในลำดับที่ถูกต้องเกือบตลอดเวลา แต่คุณไม่สามารถวางใจได้!

สุดท้าย แม้ว่า UDP จะไม่เพิ่ม IP มากนัก แต่ก็รับประกันสิ่งหนึ่งได้ หากคุณส่งต่อแพ็กเก็ต มันจะมาถึงอย่างสมบูรณ์หรือไม่ได้เลย ดังนั้น หากคุณส่งแพ็กเก็ตขนาด 256 ไบต์ไปยังคอมพิวเตอร์เครื่องอื่น คอมพิวเตอร์จะไม่สามารถรับเฉพาะ 100 ไบต์แรกจากแพ็กเก็ตได้ แต่จะต้องรับทั้งหมด 256 ไบต์ นี่เป็นสิ่งเดียวที่รับประกันโปรโตคอล UDP - ทุกสิ่งทุกอย่างตกอยู่บนบ่าของคุณ

ดังนั้นเราจึงต้องตัดสินใจว่า - เราควรใช้ซ็อกเก็ต TCP หรือ UDP หรือไม่ มาดูคุณสมบัติของพวกเขากันดีกว่า:

  • ใช้หลักการเชื่อมต่อ
  • รับประกันการส่งมอบและการตอบสนอง
  • แยกข้อมูลออกเป็นแพ็กเก็ตโดยอัตโนมัติ
  • ทำให้มั่นใจได้ว่าข้อมูลจะไม่ถูกส่งมากเกินไป (การควบคุมการไหลของข้อมูล)
  • ใช้งานง่าย - เหมือนเขียน/อ่านจากไฟล์
UDP:
  • ไม่ใช้หลักการเชื่อมต่อ - คุณจะต้องดำเนินการด้วยตนเอง
  • ไม่รับประกันการจัดส่งและลำดับการจัดส่งพัสดุ - อาจมาถึงในลำดับที่ไม่ถูกต้อง ซ้ำกัน หรือไม่มาถึงเลย!
  • คุณต้องแยกข้อมูลออกเป็นแพ็กเก็ตด้วยตนเองแล้วส่ง
  • คุณต้องระวังอย่าส่งข้อมูลมากเกินไป
  • หากแพ็กเก็ตสูญหาย คุณจะต้องติดตามมัน และส่งใหม่หากจำเป็น
ด้วยรายการดังกล่าว วิธีแก้ปัญหาดูเหมือนชัดเจน - TCP ใช้ฟังก์ชันทั้งหมดที่เราต้องการและใช้งานง่ายกว่า ในขณะที่ใช้ UDP สัญญาว่าโรคริดสีดวงทวารด้วยการเขียนทุกอย่างด้วยตนเองตั้งแต่เริ่มต้น เราก็ใช้ TCP ใช่ไหม?

แต่ไม่มี

การใช้ TCP อาจเป็นข้อผิดพลาดที่เลวร้ายที่สุดที่คุณสามารถทำได้เมื่อพัฒนาเกมที่มีผู้เล่นหลายคน เพื่อทำความเข้าใจว่าทำไม เรามาดูกันว่าอะไรทำให้ TCP ใช้งานง่ายมาก!

TCP ทำงานอย่างไร
TCP และ UDP ทำงานบน IP ทั้งคู่ แต่ในความเป็นจริงแล้ว ทั้งสองมีความแตกต่างกันโดยสิ้นเชิง UDP มีพฤติกรรมคล้ายกับ IP มาก ในขณะที่ TCP จะสรุปผู้ใช้ออกจากปัญหาแพ็กเก็ตทั้งหมด ทำให้การโต้ตอบกับ IP คล้ายกับการอ่าน/เขียนไฟล์

แล้วเขาจะทำอย่างไร?

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

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

TCP มีตัวเลือกในการแก้ไขปัญหานี้ - “TCP_NODELAY” มันบอกโปรโตคอลว่าอย่ารอให้ข้อมูลสะสมในคิวการส่ง แต่ให้ส่งทันที

น่าเสียดายที่แม้จะติดตั้งตัวเลือกนี้แล้ว TCP ก็ประสบปัญหามากมายเมื่อใช้ในเกมออนไลน์

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

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

แต่จะเกิดอะไรขึ้นหากหนึ่งในแพ็กเก็ตไม่มาถึง? หรือหากพัสดุมาถึงผิดลำดับหรือมีของซ้ำกัน?

โดยไม่ต้องเจาะลึกรายละเอียดวิธีการทำงานของ TCP อย่างลึกซึ้งเกินไป (และนี่เป็นหัวข้อที่ซับซ้อนมาก - คุณสามารถอ่านได้ใน TCP/IP Illustrated) กระบวนการจะมีลักษณะดังนี้: TCP ส่งแพ็กเก็ต กำหนดว่าแพ็กเก็ตมาไม่ถึง และส่งแพ็กเก็ตเดียวกันไปยังผู้รับอีกครั้ง แพ็กเก็ตที่ซ้ำกันจะถูกกำจัดในฝั่งของผู้รับ และแพ็กเก็ตที่มาถึงผิดลำดับจะถูกจัดเรียงใหม่เพื่อให้ทุกอย่างเป็นไปตามที่ควรจะเป็น - เชื่อถือได้และเป็นระเบียบ

ปัญหาคือเมื่อ TCP "ซิงโครไนซ์" สตรีมข้อมูลในลักษณะนี้ หากแพ็กเก็ตสูญหาย การส่งข้อมูลจะหยุดจนกว่าแพ็กเก็ตที่สูญหายจะถูกส่งอีกครั้ง (และรับโดยปลายทาง) หากมีข้อมูลใหม่เข้ามาในขณะที่รอ ข้อมูลจะถูกเข้าคิวและคุณจะไม่สามารถอ่านได้จนกว่าแพ็กเก็ตที่สูญหายอันเดิมจะมาถึง การส่งพัสดุอีกครั้งใช้เวลานานเท่าใด? ต้องใช้เวลาไปกลับของแพ็กเก็ตเป็นอย่างน้อย (เมื่อ TCP กำหนดว่าแพ็กเก็ตใดที่ต้องส่งอีกครั้ง) บวกกับเวลาที่ใช้ในการส่งแพ็กเก็ตที่สูญหายอีกครั้ง ดังนั้น หากค่า Ping ระหว่างคอมพิวเตอร์อยู่ที่ 125 มิลลิวินาที การส่งแพ็กเก็ตอีกครั้งจะใช้เวลาประมาณหนึ่งในห้าของวินาที และในกรณีที่แย่ที่สุดอาจสูงถึงครึ่งวินาที (ลองนึกดูว่าจู่ๆ แพ็กเก็ตที่ส่งกลับก็สูญหายไปเช่นกัน) เวเสลูกะ!

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

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

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

น่าเสียดายที่ไม่มีวิธีใดที่จะเปลี่ยนลักษณะการทำงานของ TCP ได้ และไม่จำเป็นต้องเปลี่ยน เนื่องจากนี่คือความหมายของ TCP นี่เป็นความจำเป็นในการทำให้การส่งข้อมูลผ่านอินเทอร์เน็ตมีกระแสข้อมูลที่เชื่อถือได้และสม่ำเสมอ
แต่เราไม่ต้องการสตรีมข้อมูลที่เชื่อถือได้และสม่ำเสมอ

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

แต่เดี๋ยวก่อน! เหตุใดฉันจึงใช้ทั้ง UDP และ TCP ร่วมกันไม่ได้

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

แน่นอนว่า การใช้ UDP สำหรับการป้อนข้อมูลของผู้ใช้และข้อมูลสถานะโลก และใช้ TCP สำหรับข้อมูลที่ต้องรับประกันว่าจะถูกส่งจะเป็นเรื่องที่น่าสนใจ คุณอาจคิดว่าคุณสามารถสร้าง "เธรด" ของคำสั่งได้หลายชุด ตัวอย่างเช่น หนึ่งชุดสำหรับระดับการโหลด และอีกชุดหนึ่งสำหรับคำสั่ง AI คุณกำลังคิดว่า “ฉันไม่ต้องการให้ทีม AI ต้องรอคิวหากแพ็กเก็ตข้อมูลสำหรับโหลดระดับสูญหาย เพราะพวกเขาไม่เกี่ยวข้องกันโดยสิ้นเชิง!” ในกรณีนี้ คุณพูดถูก และคุณสามารถเลือกที่จะสร้างซ็อกเก็ต TCP สำหรับแต่ละสตรีมคำสั่งได้

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