سؤال

هل من الممكن أن تكون غير غير غير مرغوب فيها على مأخذ توصيل بعد أن اتصلت بالاستماع (FD ، Backlog)؟

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

سيكون الإلغاء مؤقتًا وسيلة (ربما ليست أفضل طريقة) للإشارة إلى موازن تحميل في المنبع بأن هذا التطبيق لا يمكنه قبول أي طلبات أخرى في الوقت الحالي

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

المحلول

تسمح لك بعض مكتبات المقبس برفض الاتصالات الواردة على وجه التحديد. فمثلا: GNU's CommonC ++: فئة TCPSOCKE لديه رفض طريقة.

مآخذ BSD ليس لديها هذه الوظيفة. تستطيع قبول الاتصال ثم على الفور أغلق أثناء ترك المقبس مفتوحًا:

while (running) {

  int i32ConnectFD = accept(i32SocketFD, NULL, NULL);
  while (noConnectionsPlease) {
    shutdown(i32ConnectFD, 2);
    close(i32ConnectFD);
    break;
  }

}

نصائح أخرى

بعد إغلاق المقبس ، قد لا تزال برامجك تخبرك أن المقبس "قيد الاستخدام" ، وهذا بسبب بعض الغريب الذي لا أعرفه بالضبط. لكن MinPage حول Sockets يظهر لك وجود علامة لإعادة استخدام نفس المقبس ، يسمى بتكاسل: "so_reuseaddr". قم بتعيينه باستخدام "setSockopt ()".

أغلقه. على ما أذكر؛

close(fd);

استنادًا إلى نسختك المعدلة من السؤال ، لست متأكدًا من أنك مضطر إلى "غير غير" أو إغلاق (). خياران يتبادر إلى الذهن:

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

2) إذا كنت تريد حقًا أن يظهر المنفذ مغلقًا تمامًا مؤقتًا ، فيمكنك تطبيق مرشح حزمة مستوى kernel ديناميكيًا على المنفذ لمنع محاولات الاتصال الواردة من الوصول إلى مكدس الشبكة. على سبيل المثال ، يمكنك استخدام مرشح حزمة Berkeley (BPF) على معظم منصات *NIX. هذا هو أنك تريد إسقاط الحزم الواردة القادمة إلى منفذ الاهتمام باستخدام ميزات جدار الحماية للمنصة. هذا ، بالطبع ، يختلف حسب النظام الأساسي ، ولكنه نهج ممكن.

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

وبالمثل ، سيتم إغلاق أي اتصالات كانت معلقة عند إغلاق مقبس الاستماع بدون بيانات.

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

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

لا توجد طريقة واضحة لإلغاء غير رسائل!

يمكنك إما close(fd) أو shutdown(fd, how)

fd is the socket file descriptor you want to shutdown, and how is one of the following:

0 Further receives are disallowed

1 Further sends are disallowed

2 Further sends and receives are disallowed (like close())

على المستوى الأساسي ، تكون المقابس إما مفتوحة أو مغلقة (سنتجاهل أوقات مخطط حالة TCP/IP هنا).

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

لديك خياران يمكنني رؤيتهما. إما إغلاق () المقبس عندما تريد "غير غير غير غير مرغوب فيه" ، وإعادة فتحه لاحقًا - استخدم setSockOcopt () مع علامة SO_REUSEADDR للسماح لك بالترويج للمنفذ المعروف قبل انتهاء الوقت time_wait2.

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

إليك نهجًا قبيحًا إلى حد ما يعتمد على سؤالك المعدل:

افتح مأخذ توصيل للاستماع مع تراكم عادي. يتابع.

عندما تريد "الإغلاق" ، افتح ثانياً مع تراكم 1 و SO_REUSEADDR. أغلق الأول. عندما يكون جاهزًا للاستئناف ، قم بعمل مقبس آخر مع أحدهم مع تراكم عادي.

تفاصيل إرضاء حول استنزاف قائمة انتظار قبول من المقبس الذي تغلقه ستكون القاتل هنا. ربما يكفي من القاتل لجعل هذا النهج غير قابل للحياة.

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

قد تكون قادرًا على الاتصال بالاستماع للمرة الثانية. مواصفات POSIX لا تقول لا. ربما يمكنك تسميتها للمرة الثانية مع معلمة تراكم من 0 عندما تريد "غير غير".

ما يحدث عندما يتم استدعاء الاستماع مع تراكم 0 يبدو أن التنفيذ محدد. تقول مواصفات Posix مايو السماح بقبول الاتصالات ، مما يعني أنه قد تختار بعض التطبيقات رفض جميع الاتصالات إذا كانت المعلمة المتراكمة 0. على الأرجح ، سيختار تنفيذك بعض القيمة الإيجابية عند المرور في 0 (ربما إما 1 أو SomaxConn).

السؤال لم يقل أي نوع من المقبس. إذا كان مقبس UNIX ، فيمكنك التوقف والبدء في الاستماع مع إعادة تسمية (2). يمكنك أيضًا التوقف عن الاستماع بشكل دائم باستخدام Unlink (2) ، وبما أن المقبس مفتوح ، يمكنك متابعة خدمة تراكمك. يبدو هذا النهج مفيدًا تمامًا ، على الرغم من أنني لم أر استخدامه من قبل وأنا فقط أستكشفه بنفسي.

لقد حصلت بالفعل على بعض الإجابات حول استحالة القيام بذلك عبر واجهة برمجة تطبيقات المقبس.

يمكنك استخدام أساليب نظام التشغيل الأخرى (أي مضيف Firwall/iPtables/ipfilter) لإعداد قاعدة رفض مؤقتة.

لقد وجدت أن معظم موازنات الحمل محدودة بعض الشيء في الإمكانيات التي يوفرونها للتعرف على مشاكل الاتصال (معظمهم يتعرفون على RST فقط في مسبار الاتصال ، وليس كرد على محاولة اتصال شرعية.)

على أي حال ، إذا كنت محدودًا من خلال تحقيقات الكشف عن عدم التوافر ، فأنت تقوم بإعداد مسبار مستوى التطبيق الذي يقوم بطلب HTTP أو تسجيل الدخول إلى FTP أو أشياء متشابكة ، فسيتعرف عليها إذا كنت تغلق ببساطة بعد القبول. يمكن أن يفسر حتى رسائل الخطأ مثل "500 خدمة غير متوفرة" ، والتي تبدو أنظف بالنسبة لي على أي حال. مع SNMP ، يمكن لبعض موازنات التحميل أيضًا استخدام النتيجة كتلميح.

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