9.11. كائنات المقابس¶
واجهة Python لطبقة النقل هي الصنف socket.socket. ويمثّل المقبس (socket) نقطة نهاية واحدة لمحادثة شبكية -- عنوانًا، ومنفذًا، والبروتوكول (UDP أو TCP) الذي تجري عليه المحادثة. وقد فتحت فصول التحكم بالعتاد نسخًا من UART للتحدث على سلك؛ ويفتح هذا القسم نسخًا من socket للتحدث على الشبكة. والشكل هو نفسه؛ غير أن الخدمة الأساسية أكثر قدرة بكثير.
9.11.1. إنشاء مقبس¶
تصف ثلاث وسائط مقبسًا: أي عائلة عناوين يتحدث بها، وأي نوع مقبس يقدّمه، وأي بروتوكول يستخدمه. والقيم الافتراضية تغطي الحالات التي يستخدمها بقية هذا القسم:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # IPv4 TCP
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # IPv4 UDP
الثابتان اللذان يختار التطبيق بينهما في كل الحالات تقريبًا:
AF_INET-- عناوين IPv4 (عنوان IP رقمي إضافة إلى منفذ). وهو الخيار الأكثر شيوعًا. وAF_INET6هو المكافئ لـ IPv6.SOCK_STREAM-- اتصال TCP، أي تدفق البايتات الموثوق. وSOCK_DGRAMهو المكافئ لـ UDP.
تُترك الوسيطة الثالثة (البروتوكول) عند الصفر، وهو ما يختار القيمة الافتراضية الصحيحة بناءً على الوسيطتين الأوليين. والمُنشئ الكامل موثّق في socket --- وحدة المقابس (socket).
9.11.2. العناوين على المقبس¶
عنوان المقبس هو صفّ (tuple) من (host, port)
("192.168.1.50", 80)
("0.0.0.0", 8000)
المضيف هو عنوان IP في صورة سلسلة نصية. والمنفذ هو العدد الصحيح ذو 16 بت المغطّى في المنافذ.
ثمة حفنة من سلاسل المضيف الخاصة جديرة بالمعرفة:
تعني
"0.0.0.0""كل واجهة IPv4 على هذا الجهاز". والخادم المربوط بهذا العنوان يقبل الاتصالات على أي عنوان تحمله الكاميرا.العنوان
"127.0.0.1"هو المضيف المحلي (localhost) -- وحركة المرور الموجهة إليه لا تغادر الجهاز قط. وهو مفيد للاختبار.العنوان
"255.255.255.255"هو عنوان البث المحلي. ومخطط بيانات UDP المُرسل إليه يذهب إلى كل جهاز على المقطع المحلي.
أسماء النطاقات مثل "example.com" ليست سلاسل مضيف صالحة في عنوان مقبس. إذ يجب تحليلها إلى عنوان IP أولًا؛ ويغطي الأسماء وDNS استدعاء getaddrinfo() الذي يقوم بذلك.
9.11.3. الدوران¶
تعتمد دورة حياة المقبس على أي جهة من المحادثة هو عليها. فمقبس العميل يستدعي connect() (أو، في حالة UDP، sendto() ببساطة) للتحدث إلى خادم معروف. ومقبس الخادم يستدعي bind() للمطالبة بمنفذ، ثم إما listen() وaccept() (في حالة TCP) أو recvfrom() (في حالة UDP) لاستقبال حركة المرور الواردة.
يُستخدم المُنشئ socket نفسه في كلتا الحالتين؛ ولا تختلف سوى الدوال المستدعاة بعد ذلك. وتستعرض الصفحات الثلاث التالية الأنماط العملية:
مقابس UDP -- إرسال واستقبال مخططات البيانات.
مقابس TCP -- عميل TCP وخادمه.
المقابس مع asyncio -- كل ما سبق، لكن داخل حلقة أحداث
asyncio.
9.11.4. إغلاق مقبس¶
يحمل كل مقبس قطعة صغيرة من حالة نظام التشغيل (حجز منفذ، ومخازن مؤقتة، وحالة TCP الخاصة بالاتصال). وعندما ينتهي التطبيق منه، تحرّر close() تلك الحالة. والمقبس المنسيّ تسرّب بطيء يتراكم؛ ففي حلقة تفتح اتصالات، سيؤدي إغفال close في نهاية المطاف إلى استنفاد مجموعة المقابس المتاحة لدى الكاميرا.
النمط الأنظف هو عبارة with
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect(addr)
s.send(b"GET / HTTP/1.0\r\n\r\n")
...
# socket is closed automatically here, even on error
تنفّذ المقابس بروتوكول مدير السياق المغطّى في نظرة Python العامة، لذا تضمن كتلة with استدعاء close() بغض النظر عمّا إذا خرجت الكتلة بشكل طبيعي أو بإثارة استثناء.
9.11.5. مرجع socket¶
تستعرض هذه الصفحة والصفحات التالية الواجهة البرمجية في صورة سردية. وللاطلاع على المرجع الكامل على مستوى الوسائط لكل دالة وكل راية وكل ثابت تتيحه الوحدة، انظر socket --- وحدة المقابس (socket). كما أن المرجع هو المكان الذي يُبحث فيه عن العمليات الأقل شيوعًا (خيارات المقبس، وعضوية مجموعة البث المتعدد، ومعرّفات نطاق IPv6) التي لا يغطيها هذا القسم.