سؤال

أنا في عملية تنفيذ الخدمة-مكتوبة في بيثون مع إطار الملتوية التي تعمل على ديبيان جنو/لينكس-أن يتحقق من توافر رشفة الخوادم.لهذا يمكنني استخدام أسلوب الخيارات (أ بروتوكول SIP الميزة) ، كما يبدو أن هذا ممارسة شائعة.من أجل بناء الصحيحة المتوافقة مع RFC رؤوس أنا بحاجة إلى معرفة عنوان IP المصدر و المصدر منفذ الاتصال الذي سوف يتم تأسيسها.[كيف] يمكن أن يتم ذلك مع الملتوية ؟

هذا ما حاولت:أنا ثم subclassed البروتوكول.DatagramProtocol و في startProtocol(self) اعتدت self.transport.getHost().host و self.transport.getHost().port.هذا الأخير هو في الواقع المنفذ الذي هو على وشك أن يستخدم, في حين أن الأول فقط ينتج 0.0.0.0.

أعتقد أن في هذه المرحلة الملتوية لا [ ؟ ] تعرف أي واجهة مثل أي عنوان IP المصدر سيتم استخدامها.هل الملتوية تقديم التسهيلات التي يمكن أن تساعد لي مع هذا أو هل أنا بحاجة إلى واجهة مع نظام التشغيل (التوجيه) بطريقة مختلفة ؟ أو هل أنا فقط استخدام self.transport.getHost().host بشكل غير صحيح

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

المحلول

لأغراض اكتمال أجيب سؤالي الخاصة:

تأكد من استخدام اتصال () على نقل قبل محاولة تحديد عنوان IP مصدر المضيف. يظهر المقتطف التالي الجزء ذي الصلة من تنفيذ البروتوكول:

class FooBarProtocol(protocol.DatagramProtocol):
    def startProtocol(self):
        self.transport.getHost().host   # => 0.0.0.0
        self.transport.connect(self.dstHost, self.dstPort)
        self.transport.getHost().host   # => 192.168.1.102

نصائح أخرى

إذا كنت تستخدم UDP ثم نقطة النهاية يتحدد إما:

  1. الدعوة bind() على مقبس صراحة ويعطيها عنوان
  2. إرسال الحزمة

إذا أردت المزيد من التفاصيل ، تحقق من هذا الرد.

المشكلة هي أنني لست على دراية الملتوية.من ما أستطيع أن أقول من خلال دراسة سريعة من مصدر يبدو أنك قد ترغب في استخدام مفاعل مثل t.i.d.SelectReactor بدلا من ذلك.هذا هو ما t.n.d.DNSDatagramProtocol لا تحت غطاء محرك السيارة.

إذا كنت تأخذ twisted خارج الصورة ، ثم المقتطف التالي يوضح ما يجري:

>>> import socket
>>> s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, 0)
<socket._socketobject object at 0x10025d670>
>>> s.getsockname()           # this is an unbound or unnamed socket
('0.0.0.0', 0)
>>> s.bind( ('0.0.0.0', 0) )  # 0.0.0.0 is INADDR_ANY, 0 means pick a port
>>> s.getsockname()           # IP is still zero, but it has picked a port
('0.0.0.0', 56814)

الحصول على اسم المضيف هو اصعب قليلا إذا كنت بحاجة إلى دعم العديد من واجهات شبكة الاتصال أو عناوين IPv4 و IPv6.إذا كنت يمكن أن تجعل واجهة استخدام شكلي ، ثم تمر عليه في أول الأعضاء في المجموعة إلى socket.bind() و يتم تعيين لك.

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

حظا سعيدا.

هل معرفة ما إذا كان الذي تريد القيام به هو ممكن مع تنفيذ SIP التي هي جزء من ملتوية؟

في أي حال، وكيف تعيين عنوان المصدر ومنفذ UDP في الملتوية هو يشبه إلى حد كبير الطريقة التي تضعها دون ملتوية. في ملتوية، reactor.listenUDP(port, protocol, interface) يربط مأخذ UDP إلى منفذ معين واجهة ويعالج مخططات المستلمة للبروتوكول الخاص. داخل البروتوكول، self.transport.write(msg, addr) يرسل مخطط البيانات إلى addr باستخدام عنوان التي يرتبط بها بروتوكول لكعنوان المصدر.

وقراءة السؤال مرة أخرى، وأعتقد أن الجزء الوحيد الذي كان في عداد المفقودين كانت تمر interface إلى reactor.listenUDP(...).

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