سؤال

لدي إعداد عميل / خادم بسيط. الخادم في C والعميل الذي يعزز الخادم هو Java.

مشكلتي هي أنه عندما أرسل بيانات كثيفة النطاق الترددي عبر الاتصال، مثل إطارات الفيديو، فإنها تسقط حتى نصف الحزم. أتأكد من أن I Shortment بشكل صحيح حزم UDP على جانب الخادم (يحتوي UDP على طول حمولة بحد أقصى من 2 ^ 16). لقد تحققت من أن الخادم يرسل الحزم (PrintF نتيجة SendTo ()). لكن جافا لا يبدو أن تحصل على نصف البيانات.

علاوة على ذلك، عندما أتحول إلى TCP، يمكنك الحصول على جميع إطارات الفيديو ولكن يبدأ الكمون في البناء، مما يؤدي إلى تأخير عدة ثوان بعد بضع ثوان من وقت التشغيل.

هل هناك أي شيء واضح أنني في عداد المفقودين؟ أنا فقط لا يبدو أن معرفة ذلك.

هل كانت مفيدة؟

المحلول

الحصول على أداة شبكة مثل Wireshark. حتى تتمكن من رؤية ما يحدث على السلك.

لا تقدم UDP محاولات إعادة الإرسال، لذلك إذا تم إسقاط حزمة في مكان ما، فهي ما يصل إلى البرنامج للتعامل مع الخسارة. ستعمل TCP بجد لتقديم جميع الحزم إلى البرنامج بترتيب، وتخلل Dups وطلب الحزم المفقودة بمفردها. إذا كنت تشاهد الكمون العالي، فسوف أراهن أنك سترى الكثير من فقدان الحزمة مع TCP أيضا، والذي سيظهر كإعادة إرسال من الخادم. إذا كنت لا ترى إعادة إرسال TCP، فربما لا يتعامل العميل في التعامل مع البيانات بسرعة كافية لمواكبة.

نصائح أخرى

سيكون أي بروتوكول تطبيقات يستند إلى UDP حتما عرضة لخسارة الحزم، وإعادة ترتيب وتكرار (في بعض الحالات). يمكن أن يقف "U" في UDP إلى "غير موثوق" كما هو الحال في بروتوكول مخطط بيانات غير موثوق. (حسنا، إنها تقف حقا على "مستخدم" ... ولكنها بالتأكيد طريقة جيدة لتذكر خصائص UDP.)

تحدث خسائر حزمة UDP عادة لأن حركة المرور الخاصة بك تتجاوز القدرة التخزين المؤقتة لأحد أو أكثر من "القفزات" بين الخادم والعميل. عند حدوث ذلك، يتم إسقاط الحزم ... وبما أنك تستخدم UDP، لا يوجد إعلام على مستوى بروتوكول النقل الذي يحدث هذا.

إذا كنت تستخدم UDP في تطبيق، يحتاج التطبيق إلى مراعاة طبيعة UDP غير الموثوقة، وتنفيذ آلياتها الخاصة للتعامل مع حزم إسقاط وخارجها وللأداء التحكم في التدفق. (تطبيق ينفهر حزم UDP بدون فكر له تأثير أن يكون هذا على شبكة مثقلة بالفعل هو مواطن شبكة سيئة.)

(في حالة TCP، ربما يتم إسقاط الحزم أيضا أيضا، لكن TCP يكتشف وإعادة إرسال الحزم المنخفضة، وتقليص آلية التحكم في تدفق TCP لإبطاء معدل نقل البيانات. النتيجة الصافية هي "الكمون". في

تعديل - بناء على تعليق OP، كان سبب مشكلته هو أن العميل لم يكن "الاستماع" لفترة، مما يؤدي إلى إسقاط الحزم الواردة (يفترض) من قبل نظام التشغيل العميل. الطريق لمعالجة هذا هو:

  1. استخدم موضوع Java مخصص ذلك مجرد يقرأ الحزم وأوقات الانتظار لهم للمعالجة، و

  2. زيادة حجم قائمة انتظار حزمة Kernel للمقبس.

ولكن حتى عندما تأخذ هذه التدابير، لا يزال بإمكانك الحصول على حزم. على سبيل المثال، إذا تم تحميل الجهاز، فقد لا يحصل التطبيق على شرائح وقت التنفيذ بشكل متكرر كافيا لقراءة جميع الحزم وقائمة انتظار جميع الحزم قبل أن تقوم Kernel بإسقاطها.

تحرير 2. - هناك بعض النقاش حول ما إذا كان UDP عرضة للتكرارات. من المؤكد أن UDP ليس لديه اكتشاف مكررة فطري أو منع. ولكن صحيح أيضا أن النسيج التوجيه لحزم IP الذي هو الإنترنت من غير المرجح أن تكرر الحزم تلقائيا. من المحتمل أن تحدث التكرارات، إذا حدثت، لأن المرسل قرر إعادة إرسال حزمة UDP. وبالتالي، في ذهني بينما يكون UDP عرضة لمشاكل التكرارات، فإنه لا يسببها في حد ذاته ... ما لم يكن هناك خطأ في مكدس بروتوكول OS أو في نسيج IP.

على الرغم من أن UDP يدعم الحزم حتى 65535 بايت في الطول (بما فيها رأس UDP، الذي هو 8 بايت - ولكن انظر الملاحظة 1)، لا يدعم النقل الأساسي بينك وبين الوجهة حزم الملكية الفكرية التي طويلة. على سبيل المثال.

سيتم تجزئة حزمة UDP الحد الأقصى للحجم إلى 45 نقطة منفصلة على الأقل - وإذا واحد من تلك الشظايا تضيع، تضيع حزمة UDP بأكملها. إذا كان معدل فقدان الحزم الأساسي هو 1٪، فسترى طلبك معدل خسارة حوالي 36٪!

إذا كنت ترغب في رؤية حزم أقل ضائعة، فلا ترسل حزم ضخمة - تقصر بياناتك في كل حزمة إلى حوالي 1400 بايت (أو حتى قم بإجراء اكتشافك "مسار MTU الخاص بك" لمعرفة الحد الأقصى للحجم الذي يمكنك إرساله بأمان دون تجزئة) وبعد


  1. بالطبع، يخضع UDP أيضا لقيود IP، ويحتوي مخططات بيانات IP بحجم 65535 كحد أقصى، بما في ذلك رأس IP. يتراوح رأس IP في الحجم من 20 إلى 60 بايت، لذلك قد يكون الحد الأقصى لمكابقة بيانات التطبيق القابلة للنقل داخل حزمة UDP منخفضة تصل إلى 65467.

قد تكون المشكلة هي أن تفعل مع التعامل مع المخزن المؤقت الخاص بك في UDPSocket. فقط إرسال كمية البايتات في واحد يذهب المشار إليها من قبل UDPSocket.getSendBufferSize(). وبعد يستخدم setSendBufferSize(int size) لزيادة هذه القيمة.

إذا تم استخدام #send () لإرسال Datagraprampack الأكبر من إعداد SO_SNDBUF، فمن المحدد التنفيذ إذا تم إرسال الحزمة أو التخلص منها.

IP. يدعم الحزم ما يصل إلى 65535 بايت بما في ذلك 20 BYTE IP رأس حزمة. UDP. يدعم مخططات البيانات ما يصل إلى 65507 بايت، بالإضافة إلى رأس IP 20 البايت و 8 بايت UDP رأس. ومع ذلك، فإن شبكة MTU هي الحد العملي، ولا تنس أن ذلك لا يشمل هذه البايت 28 فقط ولكن أيضا رأس إطار إيثرنت. ال حقيقة الحد العملي ل UDP غير المحدد هو الحد الأدنى من MTU من 576 بايت أقل كله النفقات العامة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top