◆ أساسيات المقبس
يستخدم PHP مكتبة مقبس Berkley لإنشاء اتصالاته. المقبس ليس أكثر من بنية بيانات. يمكنك استخدام بنية بيانات المقبس هذه لبدء جلسة بين العميل والخادم. يستمع هذا الخادم دائمًا ويستعد لإنشاء جلسة جديدة. عندما يتصل العميل بالخادم، فإنه يفتح المنفذ الذي يستمع عليه الخادم للجلسة. في هذا الوقت، يقبل الخادم طلب الاتصال الخاص بالعميل ثم يقوم بإجراء دورة. الآن يمكن للعميل إرسال المعلومات إلى الخادم، ويمكن للخادم إرسال المعلومات إلى العميل.
لإنشاء مقبس، تحتاج إلى ثلاثة متغيرات: البروتوكول، ونوع المقبس، ونوع البروتوكول العام. هناك ثلاثة بروتوكولات للاختيار من بينها عند إنشاء مأخذ توصيل. تابع القراءة أدناه للحصول على محتوى البروتوكول التفصيلي.
يعد تحديد نوع البروتوكول العام عنصرًا أساسيًا للاتصال. في الجدول أدناه نلقي نظرة على أنواع البروتوكولات الشائعة.
الجدول 1: اسم البروتوكول/الوصف الثابت
AF_INET هذا هو البروتوكول الذي تستخدمه معظم المقابس، باستخدام TCP أو UDP للإرسال، ويستخدم في عناوين IPv4.
يشبه AF_INET6 ما ورد أعلاه، ولكنه يُستخدم لعناوين IPv6.
نادرًا ما يتم استخدام البروتوكول المحلي AF_UNIX في أنظمة Unix وLinux، ويتم استخدامه عادةً عندما يكون العميل والخادم على نفس الجهاز. الجدول 2: اسم نوع المقبس/الوصف الثابت
SOCK_STREAM هذا البروتوكول عبارة عن اتصال متسلسل وموثوق ومتكامل يعتمد على تدفق البايت. هذا هو نوع المقبس الأكثر استخدامًا. يستخدم هذا المقبس بروتوكول TCP للإرسال.
SOCK_DGRAM هذا البروتوكول عبارة عن مكالمة نقل ذات طول ثابت بدون اتصال. هذا البروتوكول غير موثوق به ويستخدم UDP لاتصالاته.
SOCK_SEQPACKET هذا البروتوكول عبارة عن اتصال موثوق به مكون من سطرين يرسل حزم بيانات ذات طول ثابت للإرسال. يجب قبول هذه الحزمة بالكامل قبل أن تتمكن من قراءتها.
SOCK_RAW يوفر هذا النوع من مأخذ التوصيل وصولاً فرديًا إلى الشبكة. يستخدم هذا النوع من مأخذ التوصيل بروتوكول ICMP العام. (يستخدم ping وtraceroute هذا البروتوكول)
SOCK_RDM نادرًا ما يستخدم هذا النوع ولا يتم تنفيذه في معظم أنظمة التشغيل، وهو متوفر للاستخدام بواسطة طبقة ارتباط البيانات ولا يضمن ترتيب الحزمة. الجدول 3: اسم البروتوكول العام/الوصف الثابت
بروتوكول رسائل التحكم بالإنترنت ICMP، يُستخدم بشكل أساسي على البوابات والمضيفين للتحقق من حالة الشبكة والإبلاغ عن رسائل الخطأ
بروتوكول مخطط بيانات مستخدم UDP، وهو بروتوكول نقل غير موثوق وغير متصل
يمكن لبروتوكول التحكم في الإرسال TCP، وهو البروتوكول العام الموثوق به الأكثر استخدامًا، التأكد من وصول حزمة البيانات إلى المستلم، وفي حالة حدوث خطأ أثناء عملية الإرسال، فسيتم إعادة إرسال حزمة الخطأ.
الآن بعد أن تعرفت على العناصر الثلاثة التي تولد مأخذ توصيل، نستخدم وظيفة المقبس ()socket_create في PHP لإنشاء مأخذ توصيل. تتطلب وظيفة المقبس ()socket_create ثلاثة معلمات: بروتوكول، ونوع مأخذ توصيل، وبروتوكول عام. تقوم الدالة مقبس_إنشاء() بإرجاع نوع مورد يحتوي على المقبس إذا تم تشغيلها بنجاح، وإذا فشلت، فإنها ترجع خطأ.
Resourece المقبس_إنشاء(int Protocol, int المقبسType, int commonProtocol);
الآن قمت بإنشاء مأخذ توصيل، ثم ماذا؟ يوفر PHP العديد من الوظائف لمعالجة المقابس. يمكنك ربط مأخذ توصيل بعنوان IP، والاستماع إلى اتصال مأخذ التوصيل، وقبول مأخذ توصيل؛ الآن دعونا نلقي نظرة على مثال لفهم كيفية إنشاء الوظيفة للمقبس وقبوله والاستماع إليه.
<?php
$commonProtocol = getprotobyname("tcp");// استخدم اسم البروتوكول العام للحصول على نوع البروتوكول
$socket =ocket_create(AF_INET, SOCK_STREAM, $commonProtocol);// إنشاء مأخذ توصيل وإرجاع مثيل لمورد المقبس
المقبس_bind($socket, 'localhost', 1337);// ربط المقبس بالكمبيوتر المحلي
المقبس_listen($socket);// استمع إلى جميع اتصالات المقبس الواردة
// المزيد من وظائف المقبس في المستقبل
?>
المثال أعلاه ينشئ جانب الخادم الخاص بك. السطر الأول من المثال
$commonProtocol = getprotobyname("tcp");
استخدم اسم البروتوكول العام للحصول على نوع البروتوكول. يتم استخدام بروتوكول TCP العام هنا إذا كنت تريد استخدام بروتوكول UDP أو ICMP، فيجب عليك تغيير معلمات الدالة getprotobyname() إلى "udp" أو "icmp". البديل الآخر هو تحديد SOL_TCP أو SOL_UDP في وظيفة المقبس_إنشاء () بدلاً من استخدام وظيفة getprotobyname ().
$socket = المقبس_إنشاء(AF_INET, SOCK_STREAM, SOL_TCP);
يقوم السطر الثاني من المثال بإنشاء مأخذ توصيل وإرجاع مثيل لمورد مأخذ التوصيل. بعد أن يكون لديك مثيل لمورد مأخذ التوصيل، يجب عليك ربط مأخذ التوصيل بعنوان IP ومنفذ.
المقبس_bind($socket, 'localhost', 1337);
هنا تقوم بربط المقبس بالكمبيوتر المحلي (127.0.0.1) وربط المقبس بمنفذ 1337 الخاص بك. فأنت بحاجة إلى الاستماع لجميع اتصالات المقبس الواردة.
المقبس_الاستماع($socket);
بعد السطر الرابع، عليك أن تفهم جميع وظائف المقبس واستخدامها.
الجدول 4: وصف اسم وظيفة وظيفة المقبس
يقبل المقبس ()socket اتصال المقبس
يربط المقبس ()socket_bind المقبس بعنوان IP والمنفذ
يقوم المقبس ()socket_clear_error بمسح خطأ المقبس أو رمز الخطأ الأخير
يقوم المقبس ()Socket_Close بإغلاق مورد مأخذ التوصيل
يبدأ المقبس ()socket_connect اتصال المقبس
يفتح المقبس ()socket_create_listen مأخذ توصيل للاستماع على المنفذ المحدد
يُنشئ التابع ()socket_create_pair زوجًا من المقابس التي لا يمكن تمييزها في المصفوفة
يُنشئ المقبس ()socket_create مأخذ توصيل، وهو ما يعادل إنشاء بنية بيانات مأخذ التوصيل
المقبس_get_option() احصل على خيارات المقبس
()socket_getpeername يحصل على عنوان IP لمضيف مماثل عن بعد
يحصل المقبس ()socket_getsockname على عنوان IP الخاص بالمقبس المحلي
يضيف المقبس ()socket_iovec_add متجهًا جديدًا إلى مصفوفة مبعثر/مجمعة
المقبس_iovec_alloc() تقوم هذه الوظيفة بإنشاء بنية بيانات iovec يمكنها الإرسال والاستقبال والقراءة والكتابة
يحذف ()socket_iovec_delete ملف iovec المخصص
تُرجع الدالة مقبس_iovec_fetch() بيانات مورد iovec المحدد
يقوم المقبس_iovec_free() بإصدار مورد iovec
يقوم المقبس_iovec_set() بتعيين القيمة الجديدة لبيانات iovec
يحصل التابع ()socket_last_error على رمز الخطأ الأخير للمقبس الحالي
يستمع المقبس ()socket_listen إلى كافة الاتصالات من المقبس المحدد
يقرأ المقبس ()socket_read البيانات ذات الطول المحدد
يقرأ المقبس ()socket_readv البيانات من المصفوفة المبعثرة/المجمعة
يقوم المقبس ()socket_recv بإنهاء البيانات من المقبس إلى ذاكرة التخزين المؤقت
يقبل الدالة input_recvfrom() البيانات من المقبس المحدد، وإذا لم يتم تحديدها، فسيتم تعيينها افتراضيًا على المقبس الحالي.
يتلقى المقبس ()socket_recvmsg الرسائل من iovec
المقبس_select() اختيار متعدد
()socket_send ترسل هذه الوظيفة البيانات إلى المقبس المتصل
يرسل المقبس ()socket_sendmsg رسالة إلى المقبس
يرسل المقبس ()socket_sendto رسالة إلى المقبس على العنوان المحدد
يقوم المقبس ()socket_set_block بتعيين المقبس على وضع الحظر
()socket_set_nonblock اضبط المقبس على الوضع غير المحظور
يقوم المقبس_set_option() بتعيين خيارات المقبس
()socket_shutdown تتيح لك هذه الوظيفة إغلاق المقبس المخصص للقراءة أو الكتابة أو
يُرجع الدالة مقبس_strerror() الخطأ التفصيلي برقم الخطأ المحدد
يكتب المقبس ()socket_write البيانات إلى ذاكرة التخزين المؤقت للمأخذ
يكتب ()socket_writev البيانات إلى مصفوفات متناثرة/مجمعة، وترتبط جميع الوظائف المذكورة أعلاه بالمقابس في PHP التعليق التالي قبل هذا السطر:
ملحق=php_sockets.dll
إذا لم تتمكن من إزالة التعليق، استخدم الكود التالي لتحميل مكتبة الامتدادات:
<?php
إذا (!extension_loaded('المآخذ')) {
إذا (strtoupper(substr(PHP_OS, 3)) == "WIN") {
dl('php_sockets.dll');
}آخر{
دل('sockets.so');
}
}
?>
إذا كنت لا تعرف ما إذا كان المقبس مفتوحًا، فيمكنك استخدام الدالة phpinfo() لتحديد ما إذا كان المقبس مفتوحًا. يمكنك التحقق مما إذا كان المقبس مفتوحًا عن طريق التحقق من معلومات phpinfo.
عرض معلومات phpinfo() حول المقبس ◆ إنشاء خادم الآن دعونا نحسن المثال الأول. تحتاج إلى الاستماع إلى مأخذ توصيل معين والتعامل مع اتصالات المستخدم.
<?php
$commonProtocol = getprotobyname("tcp");
$socket =ocket_create(AF_INET, SOCK_STREAM, $commonProtocol);
المقبس_bind($socket, 'localhost', 1337);
المقبس_الاستماع($socket);
// قبول أي اتصالات واردة بالخادم
$اتصال = المقبس_قبول($socket);
إذا(اتصال $){
المقبس_الكتابة($connection, "لقد قمت بالاتصال بالمقبس...nr");
}
?>
يجب عليك استخدام موجه الأوامر الخاص بك لتشغيل هذا المثال. والسبب هو أنه سيتم إنشاء خادم هنا، وليس صفحة ويب. إذا حاولت تشغيل هذا البرنامج النصي باستخدام متصفح ويب، فهناك احتمال كبير أن يتجاوز حد الـ 30 ثانية. يمكنك استخدام الكود أدناه لتعيين وقت تشغيل لا نهائي، ولكن يوصى باستخدام موجه الأوامر للتشغيل.
set_time_limit(0);
ما عليك سوى اختبار هذا البرنامج النصي في موجه الأوامر الخاص بك:
PHP.exe example01_server.php
إذا لم تقم بتعيين المسار إلى مترجم php في متغيرات بيئة النظام لديك، فستحتاج إلى تحديد المسار إلى php.exe. عند تشغيل الخادم، يمكنك اختبار الخادم عن طريق الاتصال بالمنفذ 1337 عبر telnet.
هناك ثلاث مشاكل في جانب الخادم أعلاه: 1. لا يمكنه قبول اتصالات متعددة. 2. يكمل أمراً واحداً فقط. 3. لا يمكنك الاتصال بهذا الخادم من خلال متصفح الويب.
هذه المشكلة الأولى أسهل في الحل، حيث يمكنك استخدام تطبيق للاتصال بالخادم في كل مرة. لكن المشكلة التالية هي أنك تحتاج إلى استخدام صفحة ويب للاتصال بالخادم، وهو أمر أكثر صعوبة. يمكنك جعل الخادم الخاص بك يقبل الاتصال، ويكتب بعض البيانات إلى العميل (إذا كان يجب أن يكتبها)، ويغلق الاتصال وينتظر الاتصال التالي.
قم بتحسين الكود السابق وقم بإنشاء الكود التالي لإنشاء خادمك الجديد:
<?php
// قم بإعداد المقبس الخاص بنا
$commonProtocol = getprotobyname("tcp");
$socket = المقبس_إنشاء(AF_INET, SOCK_STREAM, $commonProtocol);
//socket_bind($socket, 'localhost', 1337); //socket_bind() يربط المقبس بعنوان IP والمنفذ
المقبس_الاستماع($socket);
// تهيئة المخزن المؤقت
$buffer = "لا توجد بيانات";
بينما (صحيح) {
// قبول أي اتصالات قادمة على هذا المقبس
$connection = مقبس_قبول($socket);//socket_accept() يقبل اتصال المقبس
printf("المقبس متصلrn");
// تحقق لمعرفة ما إذا كان هناك أي شيء في المخزن المؤقت
إذا($المخزن المؤقت != ""){
printf("هناك شيء ما في المخزن المؤقت...يتم إرسال البيانات...rn");
مقبس الكتابة($connection, $buffer . "rn"); //socket_write() يكتب البيانات إلى ذاكرة التخزين المؤقت للمأخذ
printf("كتب إلى المقبسrn");
}آخر {
printf("لا توجد بيانات في المخزن المؤقتrn");
}
// احصل على الإدخال
بينما($data = مقبس_قراءة($connection, 1024, PHP_NORMAL_READ))//socket_read() يقرأ البيانات ذات الطول المحدد
{
المخزن المؤقت $ = بيانات $؛
المقبس_الكتابة($connection, "تم تلقي المعلوماتrn");
printf("Buffer: " . $buffer . "rn");
}
مقبس_إغلاق($اتصال); //socket_clouse() يغلق مورد مأخذ التوصيل
printf("أغلق المقبسrnrn");
}
?>
ماذا يجب أن يفعل هذا الخادم؟ يقوم بتهيئة مأخذ توصيل وفتح ذاكرة تخزين مؤقت لإرسال واستقبال البيانات. إنه ينتظر الاتصال وبمجرد إجراء الاتصال، فإنه يطبع "مقبس متصل" على الشاشة على جانب الخادم. يتحقق هذا الخادم من المخزن المؤقت وإذا كانت هناك بيانات في المخزن المؤقت، فإنه يرسل البيانات إلى الكمبيوتر المتصل. ثم يرسل بعد ذلك رسالة قبول لهذه البيانات، وبمجرد قبول الرسالة، فإنه يحفظ الرسالة في البيانات، ويجعل الكمبيوتر المتصل على علم بالرسالة، ويغلق الاتصال في النهاية. عند إغلاق الاتصال، يبدأ الخادم في معالجة الاتصال التالي.
◆ من السهل إنشاء عميل للتعامل مع المشكلة الثانية. تحتاج إلى إنشاء صفحة PHP، والاتصال بمقبس، وإرسال بعض البيانات إلى ذاكرة التخزين المؤقت الخاصة بها ومعالجتها. ثم تنتظر البيانات المعالجة، ويمكنك إرسال بياناتك إلى الخادم. على اتصال عميل آخر، سيتم معالجة تلك البيانات.
يوضح المثال التالي استخدام المقابس:
<?php
// إنشاء المقبس والاتصال
$socket = المقبس_إنشاء(AF_INET, SOCK_STREAM, SOL_TCP);
$connection = المقبس_connect($socket,'localhost', 1337);
بينما($buffer = المقبس_قراءة($socket, 1024, PHP_NORMAL_READ)) {
إذا($buffer == "لا توجد بيانات") {
echo("<p>لا توجد بيانات</p>");
استراحة؛
}آخر{
// افعل شيئًا بالبيانات الموجودة في المخزن المؤقت
echo("<p>بيانات المخزن المؤقت: " . $buffer . "</p>");
}
}
echo("<p>الكتابة إلى المقبس</p>");
// اكتب بعض بيانات الاختبار إلى المقبس الخاص بنا
إذا(!socket_write($socket, “SOME DATArn”)){
echo("<p>فشلت الكتابة</p>");
}
// اقرأ أي استجابة من المقبس
بينما($buffer = المقبس_قراءة($socket, 1024, PHP_NORMAL_READ)){
echo("<p>البيانات المرسلة كانت: بعض البيانات<br> الاستجابة كانت:" . $buffer . "</p>");
}
echo("<p>تم القراءة من المقبس</p>");
?>
يوضح رمز المثال هذا اتصال العميل بالخادم. يقرأ العميل البيانات. إذا كان هذا هو الاتصال الأول الذي يصل في هذه الدورة، فسيرسل الخادم "NO DATA" مرة أخرى إلى العميل. إذا حدث هذا، يكون العميل في مقدمة الاتصال. يرسل العميل بياناته إلى الخادم، ويتم إرسال البيانات إلى الخادم، وينتظر العميل الرد. وبمجرد تلقي الرد، فإنه يكتب الرد على الشاشة.