اقرأني باللغة الإنجليزية
KCP هو بروتوكول سريع وموثوق يمكنه تقليل متوسط التأخير بنسبة 30%-40% وتقليل الحد الأقصى للتأخير بمقدار ثلاث مرات بتكلفة عرض نطاق ترددي أكبر بنسبة 10%-20% من TCP. إن تطبيق الخوارزمية البحتة ليس مسؤولاً عن إرسال واستقبال البروتوكولات الأساسية (مثل UDP). يحتاج المستخدمون إلى تحديد طريقة إرسال حزم البيانات ذات الطبقة السفلية وتقديمها إلى KCP في شكل رد اتصال. حتى الساعة تحتاج إلى تمريرها خارجيًا، ولن يكون هناك أي استدعاء للنظام داخليًا.
يحتوي البروتوكول بأكمله على ملفين مصدريين فقط، ikcp.h وikcp.c، ويمكن دمجهما بسهولة في مكدس البروتوكول الخاص بالمستخدم. ربما قمت بتنفيذ بروتوكول P2P أو بروتوكول يستند إلى UDP ولكنك تفتقر إلى التنفيذ الكامل والموثوق لبروتوكول ARQ، ثم قم ببساطة بنسخ هذين الملفين إلى المشروع الحالي، وكتابة بضعة أسطر من التعليمات البرمجية، ويمكنك استخدامه.
تم تصميم TCP لحركة المرور (كم عدد كيلوبايت من البيانات التي يمكن إرسالها في الثانية)، وينصب التركيز على الاستفادة الكاملة من عرض النطاق الترددي. تم تصميم KCP لمعدل التدفق (المدة التي يستغرقها إرسال حزمة بيانات واحدة من طرف إلى آخر)، فهو يستبدل 10%-20% من نفايات عرض النطاق الترددي لسرعة نقل أسرع بنسبة 30%-40% من TCP). . قناة TCP هي قناة كبيرة ذات معدل تدفق بطيء ولكن معدل تدفق كبير في الثانية، في حين أن قناة KCP عبارة عن قناة سريعة صغيرة ذات تدفق سريع. لدى KCP نوعان: الوضع العادي والوضع السريع ويتم تحقيق نتيجة زيادة معدل التدفق من خلال الاستراتيجيات التالية:
حساب مهلة TCP هو RTOx2. إذا فقدت ثلاث حزم متتالية، فسيصبح RTOx8، وهو أمر مخيف للغاية، ومع ذلك، بعد أن يبدأ KCP الوضع السريع، فهو ليس x2، بل x1.5 فقط (أثبتت التجارب ذلك). قيمة 1.5 جيدة نسبيًا)، مما يحسن سرعة الإرسال.
عندما يفقد TCP حزمة ما، فإنه سيعيد إرسال جميع البيانات بدءًا من الحزمة المفقودة، ويعيد إرسال KCP بشكل انتقائي ويعيد إرسال حزم البيانات المفقودة بالفعل فقط.
أرسل المرسل عدة حزم 1، 2، 3، 4، و5، ثم تلقى ACK من الطرف البعيد: 1، 3، 4، 5. عند استلام ACK3، عرف KCP أنه تم تخطي 2 مرة واحدة، واستقبل عندما ACK4 من المعروف أنه تم تخطي الحزمة 2 مرتين في هذا الوقت، ويمكن اعتبار أن الحزمة رقم 2 مفقودة وليست هناك حاجة لانتظار المهلة ويمكن إعادة إرسال الحزمة رقم 2 مباشرة، مما يتحسن بشكل كبير سرعة الإرسال عند فقدان الحزم.
من أجل الاستفادة الكاملة من عرض النطاق الترددي، يؤخر TCP إرسال ACK (NODELAY عديمة الفائدة، وبهذه الطريقة، سيحسب حساب المهلة وقتًا أكبر لـ RTT، مما يطيل عملية الحكم عند حدوث فقدان الحزمة). يمكن تعديل ما إذا كان قد تم تأخير إرسال ACK الخاص بـ KCP.
هناك نوعان من استجابات نموذج ARQ، UNA (تم استلام جميع الحزم قبل هذا الرقم، مثل TCP) وACK (تم استلام الحزم التي تحمل هذا الرقم) سيؤدي استخدام UNA وحده إلى جميع عمليات إعادة الإرسال، بينما يؤدي استخدام ACK وحده إلى حدوث ذلك تكلفة خسارة عالية جدًا في الماضي، كانت البروتوكولات تدور حول اختيار واحد من الاثنين، ولكن في بروتوكول KCP، باستثناء حزم ACK الفردية، تحتوي جميع الحزم على معلومات UNA.
يستخدم الوضع العادي لـ KCP نفس قاعدة الامتياز العادل مثل TCP، أي أن حجم نافذة الإرسال يتم تحديده من خلال أربعة عوامل: حجم المخزن المؤقت للإرسال، وحجم المخزن المؤقت للاستلام المتبقي في الطرف المتلقي، وامتياز فقدان الحزمة والبدء البطيء. ومع ذلك، عند إرسال بيانات صغيرة بمتطلبات توقيت عالية، يمكنك اختيار تخطي الخطوتين الأخيرتين من خلال التكوين واستخدام العنصرين الأولين فقط للتحكم في تردد الإرسال. على حساب العدالة الجزئية واستخدام عرض النطاق الترددي، يمكن تحقيق تأثير النقل السلس حتى عند تشغيل BT.
يمكنك تنزيل وتثبيت kcp باستخدام مدير مكتبة vcpkg:
git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh
./vcpkg integrate install
./vcpkg install kcp
يتم تحديث مكتبة kcp الموجودة في vcpkg بواسطة أعضاء فريق Microsoft والمساهمين في المجتمع. إذا كان الإصدار قديمًا، فيرجى إنشاء مشكلة أو رفع PR على مستودع vcpkg.
إنشاء كائن KCP:
// 初始化 kcp对象,conv为一个表示会话编号的整数,和tcp的 conv一样,通信双
// 方需保证 conv相同,相互的数据包才能够被认可,user是一个给回调函数的指针
ikcpcb *kcp = ikcp_create(conv, user);
تعيين وظيفة رد الاتصال:
// KCP的下层协议输出函数,KCP需要发送数据时会调用它
// buf/len 表示缓存和长度
// user指针为 kcp对象创建时传入的值,用于区别多个 KCP对象
int udp_output ( const char *buf, int len, ikcpcb *kcp, void *user)
{
....
}
// 设置回调函数
kcp->output = udp_output;
تحديث المكالمة في حلقة:
// 以一定频率调用 ikcp_update来更新 kcp状态,并且传入当前时钟(毫秒单位)
// 如 10ms调用一次,或用 ikcp_check确定下次调用 update的时间不必每次调用
ikcp_update (kcp, millisec);
أدخل حزمة الطبقة السفلى:
// 收到一个下层数据包(比如UDP包)时需要调用:
ikcp_input (kcp, received_udp_packet, received_udp_size);
بعد معالجة إخراج/إدخال بروتوكول الطبقة السفلية، يمكن أن يعمل بروتوكول KCP بشكل طبيعي. استخدم ikcp_send لإرسال البيانات إلى الطرف البعيد. يستخدم الطرف الآخر ikcp_recv(kcp, ptr, size) لتلقي البيانات.
الوضع الافتراضي للبروتوكول هو ARQ القياسي، ويجب تشغيل مفاتيح التسريع المختلفة من خلال التكوين:
وضع العمل:
int ikcp_nodelay (ikcpcb *kcp, int nodelay, int interval, int resend, int nc)
الحد الأقصى للنافذة:
int ikcp_wndsize (ikcpcb *kcp, int sndwnd, int rcvwnd);
ستحدد هذه المكالمة الحد الأقصى لنافذة الإرسال والحد الأقصى لحجم نافذة الاستقبال للبروتوكول، والذي يكون افتراضيًا 32. يمكن فهم ذلك على أنه SND_BUF وRCV_BUF الخاصين بـ TCP، لكن الوحدات مختلفة. وحدة SND/RCV_BUF هي بايت، وهذه الوحدة هي الحزم.
وحدة النقل القصوى:
بروتوكول الخوارزمية النقي ليس مسؤولاً عن اكتشاف MTU. MTU الافتراضي هو 1400 بايت. يمكنك استخدام ikcp_setmtu لتعيين هذه القيمة. ستؤثر هذه القيمة على الحد الأقصى لوحدة الإرسال عند دمج حزم البيانات وتجزئتها.
الحد الأدنى لـ RTO:
سواء كان TCP أو KCP، يوجد حد أدنى لـ RTO عند حساب RTO. حتى إذا كان RTO المحسوب هو 40 مللي ثانية، نظرًا لأن RTO الافتراضي هو 100 مللي ثانية، فلا يمكن للبروتوكول اكتشاف فقدان الحزمة إلا بعد 100 مللي ثانية. يمكن تغيير هذه القيمة يدويًا:
kcp->rx_minrto = 10 ;
يعد استخدام البروتوكول وتكوينه أمرًا بسيطًا للغاية، وفي معظم الحالات، يمكنك استخدامه بشكل أساسي بعد قراءة المحتوى أعلاه. إذا كنت بحاجة إلى مزيد من التحكم الدقيق، مثل تغيير مخصص الذاكرة لـ KCP، أو كنت بحاجة إلى جدولة اتصالات KCP بشكل أكثر كفاءة على نطاق واسع (مثل أكثر من 3500)، أو كيفية التكامل بشكل أفضل مع TCP، فيمكنك ذلك مواصلة القراءة:
القراءة ذات الصلة: يستخدم "Genshin Impact" أيضًا KCP لتسريع أخبار اللعبة
تم تشغيل KCP بنجاح على مشاريع متعددة مع مئات الملايين من المستخدمين، مما يوفر لهم تجربة شبكة أكثر استجابة وسلاسة.
مرحبا بكم في إخبارنا بالمزيد من الحالات
إذا لم تتعطل الشبكة أبدًا، فسيتصرف KCP/TCP بشكل مشابه، لكن الشبكة نفسها غير موثوقة، ولا يمكن تجنب فقدان الحزمة والارتعاش (وإلا، فلماذا نحتاج إلى بروتوكولات موثوقة مختلفة)؟ عند المقارنة مباشرة في بيئة مثالية تقريبًا مثل الإنترانت، يكون الجميع تقريبًا متماثلين، ومع ذلك، عند وضعها على الشبكة العامة، أو وضعها على شبكة 3G/4G، أو استخدام محاكاة فقدان حزم الإنترانت، تصبح الفجوة واضحة. تتمتع الشبكة العامة بمتوسط فقدان للحزم يقترب من 10% خلال فترات الذروة، ويكون الأمر أسوأ في ظل شبكات WiFi/3g/4g، مما سيؤدي إلى تأخير الإرسال.
شكرًا لـ zhangyuan، مؤلف asio-kcp، على التقييم الأفقي لـ KCP وenet وudt.
لمزيد من التفاصيل، راجع: توفر بيانات المقارنة والتقييم الأفقية مزيدًا من الإرشادات لأولئك الذين يترددون في الاختيار.
أجرى محرك خادم الألعاب الضخم متعدد اللاعبين SpatialOS نفس التقييم الذي أجراه TCP/RakNet بعد دمج بروتوكول KCP:
وقمنا بمقارنة زمن الاستجابة عند الحفاظ على 50 حرفًا في نفس الوقت بمعدل تحديث 60 هرتز من جانب الخادم، يرجى الاطلاع على تقرير المقارنة التفصيلي:
في السنوات الأخيرة، نمت الألعاب عبر الإنترنت والشبكات الاجتماعية المختلفة بشكل كبير. وبغض النظر عن الألعاب عبر الإنترنت أو الشبكات الاجتماعية التفاعلية المختلفة، فإن التفاعل والتعقيد يتزايدان بسرعة، وتحتاج جميعها إلى توصيل البيانات في وقت واحد إلى عدد كبير من المستخدمين، ستصبح تكنولوجيا النقل بطبيعة الحال عاملاً مهمًا يقيد التطوير المستقبلي، والعديد من بروتوكولات النقل المعروفة في عالم مفتوح المصدر، مثل raknet/enet على سبيل المثال، عند إنشاء إصدار، يتم إصدار مكدس البروتوكول بالكامل معًا. هذا النموذج لا يساعد على التنويع. يمكن لمشروعي فقط اختيار استخدامك أم لا، ولكن من الصعب اختيار "استخدامك جزئيًا"، لكنك تصمم مجموعة من مكدسات البروتوكول، بغض النظر عن مدى جودتها، فمن الصعب جدًا تلبية الاحتياجات المختلفة من زوايا مختلفة.
لذلك، تتمثل طريقة KCP في "تفكيك" حزمة البروتوكول بحيث يمكن للجميع تعديلها وتجميعها بمرونة وفقًا لاحتياجات المشروع. يمكنك إضافة طبقة من كود المسح الخاص بـ Reed Solomon أدناه لـ FEC، وطبقة فوقها لـ RC4/Salsa20. بالنسبة لتشفير الدفق، تم تصميم تبادل مفاتيح غير متماثل عند المصافحة، وتم إنشاء نظام توجيه ديناميكي في طبقة نقل UDP الأساسية لاكتشاف مسارات متعددة في نفس الوقت واختيار أفضل مسار للإرسال. يمكن دمج "وحدات البروتوكول" المختلفة هذه بحرية حسب الحاجة مثل وحدات البناء لضمان "البساطة" و"قابلية الانفصال"، حتى تتمكن من التكيف بمرونة مع احتياجات العمل المتغيرة. إذا لم تكن أي وحدة جيدة، فما عليك سوى استبدالها.
يجب أن يتم تخصيص حلول النقل المستقبلية بشكل عميق وفقًا لسيناريوهات الاستخدام، لذلك نمنح الجميع "وحدة بروتوكول" يمكن دمجها بحرية لتسهيل التكامل في حزمة البروتوكول الخاصة بك.
لمزيد من المعلومات، يرجى الاطلاع على قصص النجاح.
المؤلف: لين وي (skywind3000)
مرحبا بكم في متابعتي على: المدونة الشخصية وتويتر.
خلال سنوات خبرتي العديدة في مجال التطوير، كنت دائمًا أحب دراسة بعض مشكلات الاختناق في البرامج وحلها. في سنواتي الأولى، أحببت تطوير الألعاب. تابعت "برمجة VGA" للقيام برسومات الألعاب، وقرأت "برنامج الرسومات" الخاص بمايكل أبراش "دليل المطور" للقيام بالعرض الناعم. أحب اللعب ببعض التعليمات البرمجية التي يمكنها الضغط على وحدة المعالجة المركزية وتشغيلها بشكل أسرع. بعد الانضمام إلى العمل، تحول اهتمامي إلى التقنيات المتعلقة بالخادم والشبكة.
في عام 2007، بعد إنشاء العديد من الألعاب التقليدية، بدأت في دراسة مشكلة المزامنة في الألعاب سريعة الحركة. خلال هذه الفترة، كتبت العديد من المقالات، وكنت من أوائل الأشخاص الذين درسوا مشاكل المزامنة بغض النظر عن كيفية حل المزامنة، نحتاج إلى القيام بشيء ما فيما يتعلق بالنقل عبر الشبكة، بعد ترك اللعبة والتحول إلى الإنترنت، وجدت أيضًا أن العديد من المجالات لديها هذه الحاجة، لذلك بدأت في قضاء بعض الوقت في مجال النقل عبر الشبكة. ، ومحاولة تنفيذ بعض البروتوكولات المحافظة والموثوقة المعتمدة على UDP، وتقليد كود BSD Lite 4.4 لتنفيذ بعض البروتوكولات المشابهة لـ TCP لقد وجدته مثيرًا للاهتمام، ثم قمت بتنفيذ بعض الألعاب المتعلقة بشبكات التوجيه الديناميكية P2P. وُلد بروتوكول KCP في عام 2011. وهو في الأساس أحد الألعاب العديدة التي صنعتها بنفسها من حيث النقل.
مؤلف كتاب Kcptun، xtaci، هو زميلي في الكلية. كلانا متخصص في الاتصالات، وغالبًا ما ندرس معًا كيفية تحسين الإرسال.
مرحبًا بك في استخدام Alipay لمسح رمز الاستجابة السريعة أعلاه للتبرع لهذا المشروع. سيتم استخدام التبرعات لتحسين بروتوكول KCP بشكل مستمر وتحسين التوثيق.
شكرًا لـ: مينغمينغ، شينغزي، جين، فان، يانتشاو، بينكوان، شياودان، يو تشنغ، هو، شينغان، شو وي، وانغ تشوان، تشاو جانج تشيانغ، هو زيفنغ، وان شينتشاو، هي شينتشاو، ليو يانغ، هو شيانهوي، وو بييي ، هوا بن، روتاو، هو جيان. . . (أنا آسف لأنني لم أسجل القائمة السابقة) نحن في انتظار التبرعات والدعم من زملائنا في الصف.
مرحبا بكم في الاهتمام
مجموعة اتصالات KCP: 364933586 (رقم مجموعة QQ)، تكامل KCP، الضبط، نقل الشبكة والمناقشات الفنية ذات الصلة
مجموعة Gitter: https://gitter.im/skywind3000/KCP
المدونة: http://www.skywind.me
هذا المشروع موجود بفضل جميع الأشخاص الذين ساهموا فيه.