Skip to content

مقابسُ TCP وUDP مباشرةً

وصفةٌ لمهمّةٍ بعينِها: بروتوكولٌ من عندِك على TCP أو UDP، بلا HTTP. الدوالُّ مُعلَنةٌ في language-truth/builtins/sockets.yaml — ١٩ مدخلًا كلُّها مستقرّة، وتلزمُها استورد مقابس (لا شبكة).

صدى TCP — عمليّتان

الوصفةُ ههنا برنامجانِ مستقلّان لا برنامجٌ بخيطَين، وذلك مقصودٌ ومقيس: راجعِ الحدَّ المقيسَ في آخرِ الصفحة.

الخادمخادم_مقبس.ص:

sad
استورد مقابس

متغير الخادم = أنشئ_وصلة()
خصص_منفذ(الخادم، 8734)
انتظر_اتصالات(الخادم)
اطبع_سطر("أنتظرُ على المنفذ 8734")

حدد_انتظار_الاستقبال(الخادم، 15000)
متغير المتصل = اقبل_متصل(الخادم)
إذا (المتصل > 0)
    حدد_انتظار_الاستقبال(المتصل، 5000)
    متغير الرسالة = استقبل_عبر_وصلة(المتصل، 256)
    اطبع_سطر("وصلني: " + الرسالة)
    أرسل_عبر_وصلة(المتصل، "صدى: " + الرسالة)
    أغلق_وصلة(المتصل)
نهاية
أغلق_وصلة(الخادم)

العميلعميل_مقبس.ص:

sad
استورد مقابس

متغير الوصلة = أنشئ_وصلة()
اطبع_سطر(اتصل_بـ(الوصلة، "127.0.0.1"، 8734))
أرسل_عبر_وصلة(الوصلة، "مرحبا")
حدد_انتظار_الاستقبال(الوصلة، 5000)
اطبع_سطر(استقبل_عبر_وصلة(الوصلة، 256))
أغلق_وصلة(الوصلة)
bash
sad-build خادم_مقبس.ص -o خادم_مقبس.exe
sad-build عميل_مقبس.ص -o عميل_مقبس.exe

شغِّلِ الخادمَ في طرفيّةٍ ثمّ العميلَ في أخرى. مخرَجٌ مقيس:

# الخادم
أنتظرُ على المنفذ 8734
وصلني: مرحبا

# العميل
صحيح
صدى: مرحبا

دوالُّ TCP

الدالّةالوسائطُ المُعلَنةتفعل
أنشئ_وصلة()مِقبضُ مقبسٍ جديد
خصص_منفذ(الوصلة، المنفذ)٢يحجزُ منفذًا (و0 يعني منفذًا مؤقّتًا)
انتظر_اتصالات(الوصلة)١–٢يفتحُ طابورَ الاستماع
اقبل_متصل(الوصلة)١يقبلُ اتّصالًا ويُرجِعُ مِقبضَه
اتصل_بـ(الوصلة، العنوان، المنفذ)٣يتّصلُ بخادم
أرسل_عبر_وصلة(الوصلة، النص)٢يُرسِل
استقبل_عبر_وصلة(الوصلة، الحجم)١–٢يستقبلُ حتّى الحجم بايتًا
أغلق_وصلة(الوصلة)١يُغلِق
هل_متصلة(الوصلة)١حالةُ الاتّصال
منفذ_محلي(الوصلة)١المنفذَ الذي حُجِزَ فعلًا
عنوان_الطرف_الآخر(الوصلة)١عنوانَ النظير

رسالةُ UDP — عمليّتان

المستقبِل:

sad
استورد مقابس

متغير المستقبل = أنشئ_مرسال()
خصص_منفذ_رسائل(المستقبل، 8735)
حدد_انتظار_الاستقبال(المستقبل، 15000)
اطبع_سطر("أنتظرُ رسالةً على 8735")

متغير الرسالة = استقبل_رسالة(المستقبل، 256)
اطبع_سطر("وصلني: " + الرسالة)
أغلق_مرسال(المستقبل)

المرسِل:

sad
استورد مقابس

متغير المرسال = أنشئ_مرسال()
خصص_منفذ_رسائل(المرسال، 0)
اطبع_سطر("منفذي المحلي > 0: " + نص(منفذ_محلي(المرسال) > 0))
اطبع_سطر(أرسل_رسالة(المرسال، "مرحبا عبر UDP"، "127.0.0.1"، 8735) > 0)
أغلق_مرسال(المرسال)

مخرَجٌ مقيس:

# المستقبِل
أنتظرُ رسالةً على 8735
وصلني: مرحبا عبر UDP

# المرسِل
منفذي المحلي > 0: صحيح
صحيح
الدالّةالوسائطُ المُعلَنةتفعل
أنشئ_مرسال()مِقبضُ مقبسِ رسائل
خصص_منفذ_رسائل(المرسال، المنفذ)٢يحجزُ منفذًا
أرسل_رسالة(المرسال، النص، العنوان، المنفذ)٤يُرسِلُ مخطّطَ بيانات
استقبل_رسالة(المرسال، الحجم)١–٢يستقبِل
أغلق_مرسال(المرسال)١يُغلِق

إعداداتٌ مشتركة

الدالّةتفعل
حدد_انتظار_الاستقبال(المقبس، مِلّي)مهلةَ الاستقبال
حدد_انتظار_الإرسال(المقبس، مِلّي)مهلةَ الإرسال
أرسل_فورا(المقبس، صحيح)يُعطّلُ تجميعَ Nagle

اضبطِ المهلةَ قبلَ كلِّ انتظار

مقبسٌ بلا مهلةٍ يتعلّقُ إلى الأبد. والوصفتانِ أعلاه تضبطانِ المهلةَ قبلَ كلِّ اقبل_متصل واستقبل_*.

حدٌّ مقيس: الصدى داخلَ عمليّةٍ واحدة

النمطُ الشائعُ — خادمٌ في أطلق وعميلٌ في الخيطِ الرئيس داخلَ برنامجٍ واحد — لم ينجح تحتَ المترجِّم: كُتِبَ فتُرجِمَ بلا خطأٍ ثمّ عُلِّقَ حتّى انتهاءِ المهلة. وأُعيدَ القياسُ على بذرةِ المستودعِ نفسِها (tests/behavior/…/05_شبكة/061_tcp_echo_real.ص) فعُلِّقَت مثلَه — وهي موسومةٌ @skip_compiler في الشجرة، أي أنّ الفجوةَ مُعلَنةٌ ومعدودة لا مفاجأة.

فالوصفتانِ أعلاه بعمليّتَينِ لأنّ ذلك ما قِيسَ عاملًا.

مُرخَّص بموجب رخصة MIT