อะไรดีกว่า? แพ็คเก็ต TCP ขนาดเล็กจำนวนมากหรืออันยาวหนึ่งอัน? [ปิด]


16

ฉันกำลังส่งข้อมูลไปมาระหว่างเซิร์ฟเวอร์สำหรับเกมที่ฉันทำอยู่

ขณะนี้ฉันส่งข้อมูลตำแหน่งดังนี้:

sendToClient((("UID:" + cl.uid +";x:" + cl.x)));
sendToClient((("UID:" + cl.uid +";y:" + cl.y)));
sendToClient((("UID:" + cl.uid +";z:" + cl.z)));

เห็นได้ชัดว่ามันกำลังส่งค่า X, Y และ Z ที่เกี่ยวข้อง

การส่งข้อมูลเช่นนี้จะมีประสิทธิภาพมากขึ้นหรือไม่

sendToClient((("UID:" + cl.uid +"|" + cl.x + "|" + cl.y + "|" + cl.z)));

2
การสูญเสียแพ็คเก็ตมักต่ำกว่า 5% ในประสบการณ์ที่ จำกัด ของฉัน
mucaho

5
sendToClient ส่งแพ็กเก็ตจริงหรือไม่ ถ้าเป็นเช่นนั้นคุณทำมันได้อย่างไร
user253751

1
@mucaho ฉันไม่เคยวัดมันด้วยตัวเองหรืออะไร แต่ฉันประหลาดใจที่ TCP นั้นขรุขระรอบขอบ ฉันหวังว่าจะได้อะไรมากกว่า 0.5% หรือน้อยกว่านั้น
Panzercrisis มี. ค.

1
@Panzercrisis ฉันต้องเห็นด้วยกับคุณ โดยส่วนตัวฉันรู้สึกว่าการสูญเสีย 5% จะไม่เป็นที่ยอมรับ ถ้าคุณคิดถึงบางอย่างที่ฉันกำลังส่งพูดว่ามีเรือรบลำใหม่เกิดขึ้นในเกมแม้โอกาส 1% ของแพ็คเก็ตที่ไม่ได้รับก็จะหายนะเพราะฉันจะได้รับเรือรบที่มองไม่เห็น
joehot200

2
อย่าประหลาดใจเลยฉันหมายถึง 5% ในฐานะขอบเขตบน :) ในความเป็นจริงมันดีกว่ามาก
mucaho

คำตอบ:


28

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

  • 16 ไบต์ของส่วนหัว IPv4 (จะเพิ่มเป็น 40 ไบต์เมื่อ IPv6 กลายเป็นเรื่องปกติ)
  • 16 ไบต์ของส่วนหัว TCP
  • 10 ไบต์ของเพย์โหลด
  • โอเวอร์เฮดเพิ่มเติมสำหรับ data-link และโปรโตคอลเลเยอร์ทางกายภาพที่ใช้

ส่งผลให้ปริมาณการใช้ข้อมูล 42 ไบต์สำหรับการขนส่งข้อมูล 10 ไบต์ ดังนั้นคุณจะใช้แบนด์วิดท์ที่มีให้น้อยกว่า 25% และนั่นยังไม่ได้อธิบายถึงค่าใช้จ่ายที่โปรโตคอลระดับล่างเช่น Ethernet หรือ PPPoE ใช้ (แต่สิ่งเหล่านี้ยากที่จะประเมินเพราะมีทางเลือกมากมาย)

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

ด้วยเหตุผลดังกล่าวคุณควรพยายามส่งข้อมูลทั้งหมดที่คุณมีอยู่พร้อมกันใน TCP เซ็กเมนต์เดียว

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

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


1
ค่าโสหุ้ยจากวิธีการกู้คืนแพ็กเก็ต TCP แตกต่างกันไปหรือไม่ขึ้นอยู่กับขนาดของแพ็คเก็ต
Panzercrisis

@Panzercrisis เฉพาะในขณะที่มีแพ็คเก็ตขนาดใหญ่ซึ่งจะต้องมีการส่งอีกครั้ง
Philipp

8
ฉันจะทราบว่าระบบปฏิบัติการจะใช้ Nagles Algorithm เกือบจะแน่นอนen.wikipedia.org/wiki/Nagle%27s_algorithmกับข้อมูลขาออกซึ่งหมายความว่ามันไม่สำคัญว่าในแอปที่คุณเขียนแยกหรือรวมเข้าด้วยกันมันจะรวมเข้าด้วยกัน ก่อนที่จะส่งผ่านทาง TCP
Vality

1
@Vality API ซ็อกเก็ตส่วนใหญ่ที่ฉันใช้อนุญาตให้เปิดใช้งานหรือปิดใช้งาน nagle สำหรับแต่ละซ็อกเก็ต สำหรับเกมส่วนใหญ่ฉันอยากจะแนะนำให้ปิดการใช้งานเพราะโดยทั่วไปเวลาแฝงต่ำมักจะสำคัญกว่าการประหยัดแบนด์วิดท์
Philipp

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

10

หนึ่งขนาดใหญ่ (ภายในเหตุผล) จะดีกว่า

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

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


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

6
@ joehot200 คำตอบเดียวที่ถูกต้องคือ "ขึ้นอยู่กับ" มันมีประสิทธิภาพมากขึ้นสำหรับการส่งข้อมูลจำนวนมากใช่ แต่ไม่ใช่สำหรับการสตรีมแบบเรียลไทม์ซึ่งเกมนั้นต้องการ
D-side

4
@ joehot200: อัลกอริทึมของ Nagle โต้ตอบได้ไม่ดีกับอัลกอริธึมตอบรับช้าซึ่งบางครั้งการใช้ TCP การใช้งาน TCP บางอย่างจะล่าช้าในการส่ง ACK หลังจากที่พวกเขาได้รับข้อมูลบางอย่างหากพวกเขาคาดหวังว่าจะมีข้อมูลเพิ่มเติมที่จะตามมาในไม่ช้าหลังจากนั้น (เนื่องจากการยอมรับแพ็คเก็ตในภายหลัง อัลกอริทึมของ Nagle บอกว่าหน่วยไม่ควรส่งแพ็กเก็ตบางส่วนถ้ามันส่งข้อมูลบางอย่าง แต่ไม่ได้ยินการตอบรับ บางครั้งทั้งสองวิธีมีปฏิสัมพันธ์ไม่ดีกับแต่ละฝ่ายที่รอให้คนอื่นทำอะไรบางอย่างจนกระทั่ง ...
supercat

2
... a "ตัวตั้งเวลาสติ" เตะเข้าและแก้ไขสถานการณ์ (ตามลำดับวินาที)
supercat

2
น่าเสียดายที่การปิดใช้งานอัลกอริทึมของ Nagle จะไม่ทำอะไรเลยเพื่อป้องกันการบัฟเฟอร์ในฝั่งโฮสต์อื่น ๆ การปิดใช้งานอัลกอริทึมของ Nagle ไม่ได้รับประกันว่าคุณจะได้รับการrecv()โทรหนึ่งครั้งต่อการโทรแต่ละครั้งsend()ซึ่งเป็นสิ่งที่คนส่วนใหญ่มองหา การใช้โปรโตคอลที่รับประกันสิ่งนี้เหมือนกับ UDP "เมื่อสิ่งที่คุณมีคือ TCP ทุกอย่างดูเหมือนเป็นกระแส"
Panda Pajama

6

คำตอบก่อนหน้าทั้งหมดไม่ถูกต้อง ในทางปฏิบัติมันไม่สำคัญว่าคุณจะออกsend()สายยาวหรือsend()สายเล็ก ๆ

ในฐานะที่เป็น Phillip สถานะเซ็กเมนต์ TCP มีค่าใช้จ่ายบางส่วน แต่ในฐานะโปรแกรมเมอร์แอปพลิเคชันคุณไม่สามารถควบคุมวิธีการสร้างกลุ่มได้ ในแง่ง่าย ๆ :

การsend()โทรหนึ่งครั้งไม่จำเป็นต้องแปลเป็นหนึ่งเซ็กเมนต์ TCP

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

สิ่งนี้มีความหมายหลายอย่าง แต่สิ่งที่สำคัญที่สุดคือ:

การsend()โทรหนึ่งครั้งหรือหนึ่งเซ็กเมนต์ TCP ไม่จำเป็นต้องแปลเป็นการrecv()โทรที่สำเร็จหนึ่งครั้งที่ปลายอีกด้านหนึ่ง

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

หากคุณต้องการส่งและรับ "แพ็คเก็ต" กับ TCP คุณต้องใช้เครื่องหมายเริ่มแพ็คเก็ตเครื่องหมายยาวและอื่น ๆ วิธีการเกี่ยวกับการใช้โปรโตคอลเชิงข้อความเช่น UDP แทน? UDP รับประกันการsend()โทรหนึ่งครั้งแปลเป็นหนึ่งดาตาแกรมที่ส่งและการrecv()โทรหนึ่งครั้ง!

เมื่อทุกอย่างที่คุณมีคือ TCP ทุกอย่างดูเหมือนเป็นกระแส


1
คำนำหน้าแต่ละข้อความที่มีความยาวข้อความนั้นไม่ยุ่งยาก
ysdx

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

นี่คือระบบปฏิบัติการอย่างสมบูรณ์หรือแม้กระทั่งห้องสมุดเฉพาะ นอกจากนี้คุณสามารถควบคุมได้มาก - ถ้าคุณต้องการ เป็นความจริงที่คุณไม่มีการควบคุมทั้งหมด TCP ได้รับอนุญาตให้รวมสองข้อความหรือแยกหนึ่งข้อความหากไม่เหมาะกับ MTU แต่คุณยังคงสามารถบอกทิศทางได้ในทิศทางที่ถูกต้อง การตั้งค่าการตั้งค่าต่างๆการส่งข้อความด้วยตนเอง 1 วินาทีห่างกันหรือบัฟเฟอร์ข้อมูลและส่งในหนึ่งช็อต
Dorus

@ysdx: ไม่ใช่ไม่ใช่ฝั่งผู้ส่ง แต่ใช่ที่ฝ่ายรับ เนื่องจากคุณไม่มีการรับประกันว่าคุณจะได้รับข้อมูลในที่recv()ใดคุณจึงต้องทำการบัฟเฟอร์เองเพื่อชดเชย ฉันจะจัดอันดับในความยากลำบากเช่นเดียวกับการใช้ความน่าเชื่อถือมากกว่า UDP
แพนด้า Pajama

@Pagnda Pyjama: การนำไปใช้อย่างไร้เดียงสาของฝ่ายรับคือ: while(1) { uint16_t size; read(sock, &size, sizeof(size)); size = ntoh(size); char message[size]; read(sock, buffer, size); handleMessage(message); }(ละเว้นการจัดการข้อผิดพลาดและอ่านบางส่วนเพื่อความกะทัดรัด แต่ไม่เปลี่ยนแปลงมากนัก) การทำเช่นนี้เป็นการselectเพิ่มความซับซ้อนมากขึ้นและถ้าคุณใช้ TCP คุณอาจต้องบัฟเฟอร์ข้อความบางส่วนอยู่ดี การใช้ความน่าเชื่อถือที่มีประสิทธิภาพเหนือ UDP นั้นซับซ้อนกว่านั้นมาก
ysdx

3

แพ็คเกจเล็ก ๆ มากมายใช้ได้ ในความเป็นจริงถ้าคุณกังวลเกี่ยวกับค่าใช้จ่าย TCP เพียงแค่ใส่bufferstreamที่รวบรวมได้มากถึง 1,500 ตัวอักษร (หรือสิ่งใดก็ตามที่ TCP MTU ของคุณเป็นสิ่งที่ดีที่สุดในการขอแบบไดนามิก) และจัดการกับปัญหาในที่เดียว การทำเช่นนี้จะช่วยให้คุณมีค่าใช้จ่ายประมาณ ~ 40 ไบต์สำหรับทุกแพ็คเกจเพิ่มเติมที่คุณจะสร้างขึ้น

ที่กล่าวว่ามันยังดีกว่าที่จะส่งข้อมูลน้อยลงและการสร้างวัตถุขนาดใหญ่ช่วยให้มี ofcourse มันมีขนาดเล็กเพื่อส่งกว่าที่จะส่ง"UID:10|1|2|3 UID:10;x:1UID:10;y:2UID:10;z:3ในความเป็นจริงแล้วในตอนนี้คุณไม่ควรนำล้อเลื่อนกลับมาใช้ไลบรารี่แบบโปรโตบุฟที่สามารถลดข้อมูลเช่นนั้นให้เหลือ 10 ไบต์หรือน้อยกว่า

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

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

Bottom line:ส่งข้อมูลให้น้อยที่สุดส่งแพคเกจขนาดใหญ่และอย่าเขียนวิธีการระดับต่ำของคุณเอง แต่พึ่งพาไลบรารีและวิธีการที่รู้จักกันดีเช่นbufferstreamprotobuf เพื่อจัดการกับการยกของหนัก


จริงๆแล้วสำหรับสิ่งที่ง่ายเช่นนี้มันง่ายที่จะม้วนของคุณเอง ง่ายกว่าการอ่านเอกสาร 50 หน้าเพื่อใช้ไลบรารี่ของบุคคลอื่นและหลังจากนั้นคุณยังต้องรับมือกับข้อบกพร่องและ gotchas ของพวกเขา
Pacerier

จริงการเขียนของคุณเองbufferstreamเป็นเรื่องเล็กน้อยนั่นคือเหตุผลที่ฉันเรียกมันว่าวิธีการ คุณยังคงต้องการจัดการมันในที่เดียวและไม่รวมตรรกะบัฟเฟอร์ของคุณกับรหัสข้อความของคุณ สำหรับ Object Serialization ฉันสงสัยอย่างมากว่าคุณจะได้รับสิ่งที่ดีกว่าคนอื่น ๆ ที่ใช้เวลาหลายพันชั่วโมงแม้ว่าคุณจะลองก็ตาม
Dorus

2

ถึงแม้ว่าจะเป็น neophyte ต่อการเขียนโปรแกรมเครือข่ายด้วยตัวเอง แต่ฉันต้องการแบ่งปันประสบการณ์ที่ จำกัด ของฉันด้วยการเพิ่มบางจุด:

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

เกี่ยวกับการวัดตัวชี้วัดที่ควรพิจารณาคือ:

  • ค่าเฉลี่ยและปริมาณงานในทันที
  • ค่าเฉลี่ย , สูงสุดและต่ำสุดที่ล่าช้าแบบ end-to-end สำหรับตัวชี้วัดดังกล่าวเครื่องมือที่มีอยู่สามารถให้แก้ไขอย่างรวดเร็ว ตัวอย่างเช่น: iperf ( https://iperf.fr/ ), D-ITG ( http://traffic.comics.unina.it/software/ITG/ ) เอกสารเก่าแต่ยังคงมีประโยชน์ในการปรับ TCP สามารถดูได้ที่http://dst.lbl.gov/publications/usenix-login.pdf

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

  • UDP ที่เชื่อถือได้http://sourceforge.net/projects/rudp/
  • ENET http://enet.bespin.org/ (ซึ่งอาจแทนที่การจัดการข้อความ TCP หากพบว่าทำงานได้ดีขึ้น)
  • UDT (โปรโตคอลการถ่ายโอนข้อมูลที่ใช้ UDP http://udt.sourceforge.net/ ) ซึ่งดูเหมือนจะกลายเป็นบรรทัดฐานในสถานการณ์การคำนวณของ HP

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


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

ดังนั้นสิ่งที่ดีที่สุดที่คุณสามารถทำได้คือใช้ TCP สำหรับการดำเนินการที่สำคัญหรือใช้การติดตั้งโปรโตคอลซอฟต์แวร์ UDP (ด้วย Enet ที่ง่ายและ UDT ได้รับการทดสอบอย่างดี) แต่ก่อนอื่นวัดการสูญเสียและตัดสินใจว่า UDT จะทำให้คุณได้เปรียบหรือไม่
Teodron
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.