ما هي أفضل طريقة لتنفيذ نبضات القلب في C++ للتحقق من اتصال المقبس؟

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

  •  20-08-2019
  •  | 
  •  

سؤال

يا عصابة.لقد قمت للتو بكتابة عميل وخادم بلغة C++ باستخدام sys/socket.أحتاج إلى التعامل مع موقف لا يزال فيه العميل نشطًا ولكن الخادم معطل.إحدى الطرق المقترحة للقيام بذلك هي استخدام نبضات القلب لتأكيد الاتصال بشكل دوري.وإذا لم يكن هناك شيء، حاول إعادة الاتصال كل X ثانية لفترة زمنية Y، ثم انقضاء المهلة.

هل "نبض القلب" هذا هو أفضل طريقة للتحقق من الاتصال؟

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

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

المحلول

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

وإليك نظرة عامة keepalive TCP الذي يحدد بعض الأسباب التي قد ترغب في استخدام keepalive TCP. هذا HOWTO ينكس محددة يصف كيفية تكوين المقبس الخاص بك لاستخدام keepalive TCP في وقت التشغيل.

ويبدو أنك يمكن تمكين المحافظة TCP في مآخذ ويندوز عن طريق وضع SIO_KEEPALIVE_VALS استخدام في WSAIoctl () وظيفة.

إذا كنت تستخدم مآخذ UDP عبر بروتوكول الإنترنت ستحتاج إلى بناء ضربات القلب الخاص بك إلى البروتوكول الخاص بك.

نصائح أخرى

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

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

على سبيل المثال، يمكنك استخدام المخطط التالي:

  1. يستجيب الخادم لكل استفسار.إذا لم يتلق الخادم استعلامًا لمدة دقيقتين، فسيتم إغلاق الاتصال.

  2. يرسل العميل استعلامات ويبقي الاتصال مفتوحًا بعد كل استفسار.

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

قد يكون من الأسهل مطالبة العميل بإغلاق الاتصال إذا لم يكن بحاجة إلى إرسال استعلام خلال اللحظة الماضية.نظرًا لأن العميل يبدأ جميع العمليات، فيمكنه دائمًا فتح اتصال جديد فقط إذا كان بحاجة إلى إجراء عملية جديدة.وهذا يقلل الأمر إلى هذا فقط:

  1. يقوم الخادم بإغلاق الاتصال إذا لم يتلق استعلامًا خلال دقيقتين.

  2. يقوم العميل بإغلاق الاتصال إذا لم يكن بحاجة إلى إرسال استعلام خلال دقيقة واحدة.

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

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

لاحظ أن هذا هو افتراض كنت تستخدم TCP / IP. إذا كنت تستخدم UDP، ثم وهذا هو غلاية مختلفة تماما من الأسماك، لأنه بدون اتصال.

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

إذا كنت بين يقرأ ويكتب في انتظار إدخال المستخدم، أغلق مأخذ. تصميم بروتوكول العميل / الخادم الخاص بك (على افتراض كنت أفعل هذا من جهة، وعدم استخدام أي بروتوكولات موحدة مثل http و / أو SOAP) لمعالجة هذا الأمر.

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

وربما هذا سيساعدك، TCP Keepalive HOWTO أو هذا SO_SOCKET

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