كيفية اكتشاف متى يتم استلام رسالة مخزن مؤقت بروتوكول بالكامل؟

StackOverflow https://stackoverflow.com/questions/586819

سؤال

هذا هو نوع من فرع من بلدي سؤال آخر. وبعد اقرأها إذا أردت، لكنها ليست ضرورية.

في الأساس، أدركت أنه من أجل استخدام مبتدئ C # () بشكل فعال () في رسائل كبيرة، أحتاج إلى إما (أ) قراءة طول الحزمة أولا، ثم اقرأ بالضبط أن العديد من البايتات أو (B) استخدام محدد نهاية الحزمة. سؤالي هو، إما من هذه الموجودة في المخازن المؤقتة البروتوكول؟ لم أستخدمها بعد، ولكن بعد التوثيق لا يبدو أنه يوجد رأس طول أو محدد.

إذا لم يكن كذلك، ماذا يجب أن أفعل؟ يجب أن أقوم فقط بإنشاء الرسالة ثم بادئة / لاحقة مع رأس الطول / EOP محدد؟

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

المحلول

تحتاج إلى تضمين حجم أو علامة النهاية في بروتوكولك. لا يوجد شيء مدمج في المقابس القائم على دفق (TCP / IP) بخلاف دعم دفق غير مسمى من الأمثيات يتم تقسيمه بشكل تعسفي في حزم منفصلة (ويمكن أن تسرب الحزم في العبور أيضا).

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

اختياريا يمكن إضافة تذييل الرسالة (الحجم الثابت) مع المجموع الاختباري أو حتى توقيع تشفير (اعتمادا على متطلبات الموثوقية / الأمان الخاصة بك).

يتيح لك معرفة حجم الحمولة بالاحتفاظ بقراءة عدد من البايتات التي ستكون كافية لبقية الرسالة (وإذا اكتمال قراءة مع أقل، فقم بقياس آخر للقراءة بايتات البايت المتبقية حتى يتم استلام الرسالة بأكملها).

يعمل مؤشر الرسائل النهائي أيضا، ولكن عليك تحديد كيفية التعامل مع رسالتك التي تحتوي على نفس تسلسل الثماني ...

نصائح أخرى

الاعتذار عن الوصول في وقت متأخر من الحزب. أنا مؤلف Protobuf-Net، أحد تطبيقات C #. بالنسبة لاستخدام الشبكة، يجب عليك التفكير في طرق [de] serializewithlivendprifix" - بهذه الطريقة، ستعامل تلقائيا بأطوالك. هناك أمثلة في المصدر.

لن أذهب إلى تفاصيل هائلة على وظيفة قديمة، ولكن إذا كنت تريد معرفة المزيد، أضف تعليقا وسأعود إليك.

وأنا أتفق مع مات أن رأس أفضل من تذييل الصفحة المخازن المؤقتة بروتوكول، والسبب الأساسي في أن PB هو بروتوكول ثنائي، فإنه يمثل مشكلة في التوصل إلى تذييل من شأنه أن يكون أيضا تسلسل رسالة صالحا. تعمل الكثير من البروتوكولات المستندة إلى تذييل الصفحة (عادة ما تكون منها EOL) لأن محتوى الرسائل موجود في نطاق محدد (عادة 0x20 - 0x7f ASCII).

يتمثل النهج المفيد في أن يقرأ رمز المستوى الأدنى فقط المخازن المؤقتة من المقبس وقم بتقديمها إلى طبقة تأطير تقوم بتجميع الرسائل الكاملة وتتذكرها جزئية (أقدم نهج ASYNC لهذا (باستخدام CCR) هنا, ، وإن كان لبروتوكول خط).

بالنسبة للتناسق، يمكنك دائما تحديد رسالتك كرسالة PB مع ثلاثة حقول: ثابت كثافة ثابتة مثل الطول، وهي أداة، وسلسلة البايت التي تحتوي على البيانات الفعلية. هذا يحافظ على بروتوكول الشبكة بالكامل شفافة.

TCP / IP، بالإضافة إلى UDP، تتضمن الحزم بعض الإشارة إلى حجمها. ال رأس الملكية الفكرية يحتوي على حقل 16 بت يحدد طول رأس IP و البيانات في بايت. ال رأس TCP. يحتوي على حقل 4 بت يحدد حجم رأس TCP في كلمات 32 بت. ال رأس UDP يحتوي على حقل 16 بت يحدد طول رأس UDP و البيانات في بايت.

هنا الحاجة.

باستخدام مآخذ تشغيل المطحنة القياسية في Windows، سواء كنت تستخدم مساحة الاسم System.Net.sockets في C # أو الاشياء Winsock الأصلية في Win32، فلن ترى رؤوس IP / TCP / UDP. يتم تجريد هذه الرؤوس بحيث تحصل عليه عند قراءة المقبس هو الحمولة الفعلية، أي البيانات التي تم إرسالها.

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

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

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

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