طبقة النقل
| العنصر | القيمة |
|---|---|
| النقل | TCP (اتصال دائم) |
| المنفذ الافتراضي | 5225 |
| خيارات المقبس | تفعيل TCP_NODELAY — يرسل الحزم الصغيرة فورًا دون تأخير Nagle التجميعي |
| TLS | اختياري — إذا كان للخادم شهادة مضبوطة، يُغلَّف التدفق بأكمله بـ TLS أحادي الاتجاه (مصادقة الخادم) |
| الترميز | حقول ثنائية بعرض ثابت + مفاتيح UTF-8. الأعداد الصحيحة big-endian (ترتيب الشبكة) |
| نهاية الإطار | بايت \n واحد. لا معالجة لـ \r |
| الإطار الفارغ | \n وحده (موضع op هو \n) يُتجاهل بصمت كإشارة keep-alive |
| أقصى حجم frame | 192 bytes — يشمل op دون \n (التجاوز → E line_too_long ثم إغلاق الاتصال) |
| الأنبوب (pipelining) | مسموح — قد تصل الاستجابات بترتيب مختلف عن الطلبات |
| مهلة الخمول | لا توجد — لا يغلق الخادم أبدًا اتصالًا هادئًا |
| زمن تقدم frame | 5 ثوان كحد أقصى من أول op byte حتى fixed header وLF؛ لا يشغل الإرسال الجزئي الاتصال بلا نهاية |
ترتيب إنشاء الاتصال
- اتصال TCP
- مصافحة TLS، إذا كان TLS مفعّلًا على الخادم — الاتصال بخادم TLS بنص صريح يُقطع عند هذه الخطوة
- مصافحة المصادقة، مرة واحدة
- تبادل إطارات بروتوكول القفل بعد ذلك
قواعد التأطير (Framing)
كل رسالة هي إطار واحد = سطر واحد.
[ op: بايت واحد ][ رأس ثابت خاص بـ op ][ جسم متغير ] \nيجب على المستقبِل النظر إلى op وقراءة الرأس الثابت حسب عدد بايتاته أولًا، ثم البحث عن \n بعد ذلك فقط. السبب أن الرأس الثابت ثنائي وقد يحتوي على 0x0A (\n) كقيمة (مثل lease=10 → 0A). لا يُطبَّق البحث عن \n إلا على الجزء الأخير من النص/المفتاح.
| الاتجاه | op | الرأس الثابت |
|---|---|---|
| العميل ← الخادم | A | 10 bytes (wait:u8 + lease:u8 + owner:u64 BE) |
| العميل ← الخادم | R | 8 bytes (token:u64 BE) |
| الخادم ← العميل | A | 16 bytes (token:u64 BE + owner:u64 BE) |
| الخادم ← العميل | T · B | 8 bytes (owner:u64 BE) |
| الخادم ← العميل | R · N | 8 bytes (token:u64 BE) |
| الخادم ← العميل | M · L · E | 0 bytes (address/reason UTF-8 text) |
إذا تجاوز frame مقدار 192 bytes أو كان malformed، يعمل الخادم flush لـE إن أمكن ثم يغلق الاتصال. يعامل العميل كذلك malformed وoversized وop المجهول وE غير القابل للربط كـconnection-fatal. لا يُعاد تلقائيًا acquire أُرسل منه بايت واحد في تلك session، ويصبح Indeterminate بلا استجابة نهائية.
المصطلحات
- الإطار (frame) — الوحدة التي يُقطَّع إليها تدفق البايتات المتواصل (TCP) ليعني "رسالة واحدة". في هذا البروتوكول، كل سطر منتهٍ بـ
\nهو إطار واحد. - big-endian — ترتيب البايتات الذي يكتب البايت الأكثر أهمية أولًا. هو المعيار في بروتوكولات الشبكة، لذا يُسمى أيضًا ترتيب الشبكة (network order).
- الأنبوب (pipelining) — إرسال الطلب التالي دون انتظار استجابة الطلب السابق. تراكب زمن الرحلة ذهابًا وإيابًا بهذه الطريقة يرفع الإنتاجية.
- keep-alive — إشارة بلا معنى تُرسَل دوريًا للإعلان عن أن الاتصال ما زال حيًا. هنا، الإطار الفارغ (
\n) يؤدي هذا الدور.