برنامه نویسی سوکت در PHP

  • آپدیت شده در تاریخ

برنامه نویسی سوکت در PHP

در این آموزش قصد داریم توابع مربوط و نحوه استفاده از آن , برای برنامه نویسی سوکت در PHP را به شما در قالب مثال به شما نشان بدیم

زمانی که شما اقدام به چت کردن میکنید با یک سیستم دیگر در حال ارتباط هستید که این ارتباط از طریق یک سری پروتکل های از قبل تعریف شده نظیر TCP و UDP  انجام می گیرد. و در اینجاست که برنامه نویسی سوکت این امکان را به شما میدهد تا بتوانید با کامپیوتر مقصد خود ارتباط برقرار کرده و اطلاعات خود را ارسال و دریافت کنید.

سوکت‌ها برای ارتباط بین پردازنده‌ها معمولا مورد استفاده قرار می‌گیرند. ارتباط بین پردازنده‌ها به معنی ارتباط بین یک سرور و یک وسیله‌ی هوشمند است که اصول و اساس این ارتباط روی کلاینت-سرور می‌باشد.

از کاربرد های برنامه نویسی سوکت میتوان در نرم افزار و یا اسکریپت چت روم نام برد.

در مقاله آموزش برنامه نویسی سوکت در PHP ارتباطی بین سرور و کلاینت (نرم‌افزار) ایجاد کرده و آن را بررسی می‌کنیم. برنامه‌نویسی سوکت یا سوکت پروگرمینگ (Socket Programming) برای برقراری ارتباط امن و پایدار بین نرم‌افزار و سرور مورد استفاده قرار می‌گیرد.

شروع به کد‌نویسی

یکبار دیگر هدف اصلی از ارائه‌ی مقاله برنامه نویسی سوکت در PHP را خدمت شما عزیزان مطرح می‌کنیم:

برنامه‌نویسی و توسعه یک نرم‌افزار سمت کلاینت برای ارسال پیام به سرور و برنامه‌نویسی سمت سرور برای پاسخ به پیام کاربر به گونه‌ای که پیام را به صورت معکوس ارسال کند. مثلا به سرور عبارت «سلام» را بفرستیم و سپس پاسخ «مالس» دریافت کنیم (معکوس پیام)

برنامه نویسی سوکت در PHP

سرور PHP

مرحله ۱: تنظیم کردن متغییرهایی مانند host و port

در ابتدا برای شروع برنامه نویسی سوکت در PHP , یک فایل به نام server.php ایجاد کرده و سپس در خطوط اول آن آدرس پورت و آی پی هاست خود را تعریف کنید:

توجه داشته باشید که پورت می‌تواند هر عددی بین ۱۰۲۴ تا ۶۵۵۳۵ باشد.

مرحله ۲: ساخت سوکت

با استفاده از دستور زیر نسبت به ایجاد و ساخت سوکت با استفاده از توابع از پیش تعریف شده می‌پردازیم:

در دستور فوق همانطور که ملاحظه می‌کنید از تابع socket_create جهت ایجاد یک سوکت استفاده کردیم. این تابع سه آرگومان به نام‌های domain، type و protocol دارد که در زیر به شرح هر یک می‌پردازیم.

تابع socket_create:

این تابع یک منبع سوکت ایجاد کرده و به نقطه پایانی اتصال و ارتباط اشاره می‌کند. شبکه‌های ارتباطی معمول از ۲ سوکت ساخته شده‌اند که یکی از آنها وظایف سمت کلاینت و دیگری وظایف سمت سرور را معرفی می‌کند. در ادامه به توضیح هر یک از آرگومان‌ها می‌پردازیم:

domain:

پارامتر domain برای معرفی و مشخص کردن خانواده پروتکل مورد استفاده توسط سوکت می‌باشد که این پارامترها به شرح زیر است:

  • AF_INET: پروتکل‌هایی که برا اساس IPv4 هستند که از معروفترین و معمول‌ترین این خانواده پروتکل می‌توان به TCP و UDP اشاره کرد. همانطور که در جریان هستید IPv4 یک اینترنت پروتکل (Internet Protocol) می‌باشد که به صورت دودویی آدرس‌دهی می‌شود و ۲ به توان ۳۲ آدرس‌دهی هم اکنون در شبکه اینترنت جهانی موجود می‌باشد و یک اینترنت پروتکل برای ارتباط بین دو وسیله هوشمند دارای پردازنده است.
  • AN_INET6: پروتکل‌هایی که برا اساس IPv6 هستند که از معروفترین و معمول‌ترین این خانواده پروتکل می‌توان به TCP و UDP اشاره کرد. این اینترنت پروتکل  ۲ به توان ۱۲۸ آدرس‌دهی در سطح اینترنت دارد که به عنوان نسل جدید و انقلابی در زمینه اینترنت پروتکل شناخته می‌شود.
  • AN_UNIX: خانواده پروتکل ارتباط محلی (Local Communication Protocol) می‌باشد. بازدهی بالا و  مخارج کمتر این پروتکل را به عنوان یکی از بزرگترین‌ترین شکل‌های ارتباطی IPC کرده است. IPC مخفف عبارت Inter Process Communication است.

Type:

پارامتر type نوع ارتباط مورد استفاده توسط سوکت را مشخص می‌کند که شامل مقادیر زیر است:

  • SOCK_STREAM: دارای ویژگی‌هایی چون ایجاد پیوستگی، قابل اعتماد، کاملا دوپلکس (Full-Duplex)، مبنی بر اتصالات بایت. یک مکانیزم انتقال داده فرا مرزی. پروتکل TCP بر اساس این نوع سوکت است.
  • SOCK_DGRAM: دیتاگرام (datagram)‌ را پشتیبانی می‌کند و دارای ویژگی‌هایی چون برقراری اتصال، پیام‌هایی که بیش از یک طول مشخص باشند را مخرب شناسایی می‌کند. پروتکل UDP بر اساس این نوع سوکت است.
  • SOCK_SEQPACKET: دارای ویژگی‌هایی چون ایجاد پیوستگی، قابل اعتماد، دارای ارتباط دو طرفه بر اساس مسیر انتقال داده برای دیتاگرام‌هایی با طول متنی مشخص.
  • SOCK_RAW: دسترسی خام پروتکل شبکه را ایجاد می‌کند. این نوع خاص از سوکت است که می‌تواند برای سازنده‌های هر نوع پروتکل مورد استفاده قرار بگیرد. یک راه معمول برای این نوع سوکت پاسخ دادن به درخواست‌های ICMP مانند ping است.
  • SOCK_RDM: یک لایه‌ی دیتاگرام امن و قابل اعتماد را ایجاد می‌کند که کمتر مورد استفاده قرار می‌گیرد زیرا معمولا در سیستم عامل‌ها موجود نیست.

protocol:

پارامتر protocol یک پروتکل مشخص را برای یک domain هنگام بازگردانی ارتباط از سمت سوکت، مشخص تعیین می‌کند. با استفاده از تابع getprotobyname می‌توان مقدار مناسبی را بر اساس بازگردانی اسم اعمال کرد.

مرحله ۳:‌ اتصال سوکت به پورت و هاست

در این مرحله منبع سوکت ایجاد شده را به IP و Port موردنظر با استفاده از تابع socket_bind متصل می‌کنیم:

مرحله ۴: انتظار برای اتصال سوکت

در این مرحله سرور برای اتصال کاربر یا کلاینت منتظر می‌ماند و تا زمانیکه اتصال برقرار نشود، سرور منتظر می‌ماند. عددی که به عنوان پارامتر دوم به این تابع ارسال می‌شود به معنی تعداد اتصالاتی‌ست که در صف انتظار قرار می‌گیرد. یعنی اگر همزمان ۳ اتصال دیگر به این سوکت وجود داشته باشد آنها را منتظر نگه می‌دارد و اگر ۴ امین اتصال برقرار شود، سوکت قطع شده و این اتصال را رد می‌کند.

مرحله ۵: پذیرفتن راه ارتباطی

تابعی که در این مرحله مورد استفاده قرار می‌گیرد، درخواست برقراری ارتباط را در سوکت ایجاد شده بررسی و می‌پذیرد. پس از پذیرفتن ارتباط از سوکت کلاینت یا کاربر، این تابع منبع سوکت دیگری را که برای برقراری ارتباط با سوکت کلاینت پاسخگو است را باز می‌گرداند. در این مثال متغییر spawn به عنوان یک پاسخ برای ارتباط با سوکت کلاینت به کار گرفته می‌شود:

با انجام اینکار سوکت سرور خود را آماده کرده‌ایم اما در عمل فعلا اسکریپت ما کار خاصی را انجام نمی‌دهد. هدف ذکر شده در ابتدای این مقاله را به یاد بیاورید. ما متن پیامی را از سوکت کاربر خوانده و سپس پاسخ آن را به مجددا به صورت معکوس شده به همان سوکت کاربر از طریق سرور ارسال می‌کنیم.

مرحله ۶: خواندن پیام از سوکت کاربر

برای انجام اینکار از یک تابع به نام socket_read استفاده می‌کنیم:

با استفاده از این تابع می‌توان حداکثر بایتی که یک سوکت بتواند بخواند را مشخص کرد.

مرحله ۷: معکوس کردن پیام دریافتی

حال خروجی را تعیین کرده و با استفاده از تابع strrev پیام را معکوس می‌کنیم:

مرحله ۸: ارسال پیام به سوکت کاربر

با بهره گیری از تابع socket_write می‌توان پیام را به سوکت کاربر ارسال کرد:

مرحله ۹: بستن سوکت

پس از انجام مراحل فوق باید سوکت را ببندیم. بنابراین ابتدا متغییر spawn را بسته و سپس سوکت اصلی را که در متغییر socket جای گرفته را می‌بندیم.

با انجام این مراحل اسکریپت سمت سرور را به صورت کامل انجام داده‌ایم. حال نوبت به اسکریپت سمت کاربر می‌رویم.

کلاینت PHP

دو مرحله‌ی اول برای نوشتن اسکریپت سمت کاربر در برنامه نویسی سوکت در PHP  دقیقا مشابه اسکریپت سرور می‌باشد. یعنی ما ابتدا پورت و هاست را مشخص کرده و سپس به تولید یک سوکت می‌پردازیم و در نهایت آنها را به هم متصل می‌کنیم. برای انجام اینکار یک فایل با نام client.php در فولدری که فایل server.php را قرار داده‌اید، ایجاد کنید.

مرحله ۱: تنظیم کردن متغییرهای مربوط به هاست و پورت

توجه داشته باشید که متغییرهای host و port باید دقیقا مشابه آنچه در سرور تعریف شده است، مقداردهی شوند. همچنین یک متغییر به نام message جهت ارسال پیام موردنظر به سرور تعریف شده است.

مرحله ۲: ساخت سوکت

مرحله ۳:‌ اتصال به سرور

توجه داشته باشید برخلاف سمت سرور، در سمت کلاینت نیازی به اتصال و بایند کردن هاست و پرت نیست. به جای آن به سوکت سرور متصل شده و منتظر پذیرش ارتباط از سمت سوکت کلاینت خواهیم بود. اتصال سوکت کلاینت به سرور در این مرحله پایدار و تثبیت می‌شود.

مرحله ۴: نوشتن سوکت سرور

در این مرحله داده سوکت کاربر یا کلاینت به سوکت سرور ارسال می‌شود.

مرحله ۵: خواندن و نمایش پاسخ ارسالی از سمت سرور

مرحله ۶: بستن سوکت

حمع بندی

بنابراین کدهای ما به صورت کامل به شرح زیر می‌باشند:

فایل server.php

فایل client.php

پس از انجام تمام مراحل فوق باید روند زیر را جهت دریافت نتیجه انجام دهید:

  1. ابتدا این فایل‌ها را در دایرکتوری www موجود در WAMP یا htdocs موجود در Xampp کپی کنید.
  2.  داخل فایل php.ini موجود در زمپ یا ومپ خود به دنبال عبارت extension=php_sockets.dll بگردید و سپس علامت ; را از ابتدای آن بردارید تا سوکت PHP شما فعال شود.
  3. مرورگر خود را باز کرده و آدرس localhost را تایب کنید.
  4. ابتدا فایل server.php را و سپس فایل client.php در مرورگر خود باز کنید.

نکته : در صورت مواجه شدن با خطای زیر مقدار عددی پورت را تغییر دهید. این مقدار می‌تواند بین ۱۰۲۴ تا ۶۵۵۳۵ باشد:

به همین سادگی کار به اتمام می‌رسد و شما بین دو سوکت سرور و کلاینت (کاربر) اتصال برقرار کرده‌اید. امیدواریم آموزش برنامه نویسی سوکت در PHP مورد پسند شما عزیزان واقع شده باشه .

هرگونه مشکلی در پیاده سازی کدها داشتید ، از قسمت نظرات اقدام کنید . سریعا ، پاسخگوی سوالات شما هستیم .

موفق و پیروز باشید.

حسن شفیعی توسعه دهنده وب و موبایل مدیر سایت علاقه خاصی به برنامه نویسی وب و موبایل دارم و هر روز تلاش می کنم به این حوزه مسلط تر شوم و اطلاعاتم را به شکل کاربردی برای علاقه مندان در وب به اشتراک بگذارم. اگر نیاز به برنامه نویس برای انجام پروژه و نوشتن اسکریپت های سمت وب, اپلیکیشن های اندروید و ios, پیدا کردن راه حل توسعه و غیره داشتید حتما از طریق تماس با ما/ واتساپ/ تلگرام بهم پیام بدید. برایتهیه هاست مطمین و پرسرعت کلیک کنید
مطالب زیر را حتما بخوانید
دیدگاه کاربران (۲۲)

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

  1. سیدسروش حسینی ۱۰ فروردین ۱۴۰۳

    سلام عزیز
    یک سوال داشتم
    الا شما یک سرور نوشتید و یک کلاینت میخواستم بدونم اگه قرار باشه ما کد کلاینت رو در یک هاست مجزا نسبت به هاستی که کد سرور رو ران میکنه اجرا کنیم باز هم کلاینت ما پاسخ میده و کار میکنه یا خیر؟

    اگه خیر چگونه میشه کاری کرد که کار کنه؟

    بعد اینکه من میخواستم یک چیزی مشابه وبسوکت زیر بنویسم پیشنهادتون چه هاستی با چه مشخصاتی هست؟

    ایا هاست نیاز به ip اختصاصی و فعال بودن ترمینال داره؟

    – wss://shsocket1.iranlms.ir:80

    پاسخ
    1. حسن شفیعی ۱۰ فروردین ۱۴۰۳

      سلام
      نیاز نیست حتما یه هاست باشن میتونه جدا باشه
      برای وبسوکت زیر که گفتید باید سرور مجازی یا اختصاصی اوبونتو داشته باشید

      پاسخ
  2. افشین ۱۵ آذر ۱۴۰۲

    سلام
    من برنامه شما را رای یک کارت ادام نوشتم و پیام خطای can not bind را میده و اتصال برقرار نمیشه ممنون میشم راهنمایی بفرمایید

    پاسخ
    1. حسن شفیعی ۲۹ آذر ۱۴۰۲

      سلام. باید کد دقیق باشه تا فهمید مشکل چیه

      پاسخ
  3. افشین ۱۳ آذر ۱۴۰۲

    سلام لطفا توابع ایجاد سوکت در php را چطوری اضافه کنیم توابع کتابخانه ش نداریم ممنون میشم راهنمایی بفرمایید

    پاسخ
    1. حسن شفیعی ۱۴ آذر ۱۴۰۲

      سلام.
      توابع socket_ بصورت پیش فرض داخل php فعال هست اگر فعال نبود به هاستینگ بگید فعال کنن

      پاسخ
  4. امیر ۲۶ فروردین ۱۴۰۰

    سلام
    ۱- اگر به هر دلیلی سرور Restart بشه ، کلاینت آی دی هایی که قبلا در دیتابیس ذخیره کرده بودم چه بلایی سرشون میاد ؟
    ۲- چه راه حلی پیشنهاد میکنین برای اینکه کلاینت آی دی رو بشه به صورت Custom برای هر کاربر ثبت و ذخیره کرد ؟
    ۳- لطفا به ایمیل من یه ایمیل بدید برای مشاوره نیاز دارم که باهاتون صحبت کنم . ممنونم

    پاسخ
  5. هاشم شیخی ۱۹ اسفند ۱۳۹۹

    سلام
    ممنون از توضیحات خوب شما در مورد سوکت نویسی در php
    در مورد ratchet websocket سوالی دارم اگر پاسخگو هستید بپرسم

    پاسخ
    1. حسن شفیعی ۱۹ اسفند ۱۳۹۹

      سلام. خوشحالیم که مفید واقع شده.
      متاسفانه در این مورد اطلاعاتی ندارم که خدمت شما راهنمایی ارایه بدم

      پاسخ
  6. علی ۲ اسفند ۱۳۹۸

    سلام.
    این فایل سرور که نوشتید رو اگر بخواهیم روی یک سرور واقعی بزاریم، چه نوع سروری میخواد و توی فایل منیجر اون، باید این فایل رو کجای سرور بزاریم.

    پاسخ
    1. حسن شفیعی ۳ اسفند ۱۳۹۸

      سلام. یک هاست معمولی لینوکس بخرید و در گوگل نحوه آپلود روی هاست رو جستجو کنید.
      همچنین تا زمانی که php را تا حد متوسط یاد نگرفتید از این آموزش بهره زیادی نخواهید برد.
      موفق باشید.

      پاسخ
      1. علی ۳ اسفند ۱۳۹۸

        ممنون از پاسختون.
        هاست دارم، نحوه ی آپلود با سی پنل هم بلدم. قصدم اینه که با نرم افزار اندروید که کد های اون رو نوشتم، به این سرور سوکت وصل بشم. فقط نمیدونم این فایل سرور رو تو کدوم بخش فایل های هاستم بزارم و فعالش کنم که گوش کنه.

        پاسخ
      2. حسن شفیعی ۳ اسفند ۱۳۹۸

        این سوکت رو در بخش public_html قرار میدید و بعد کرون جاب رو روش فعال می کنید.
        برای دسترسی به آن هم نیاز است که api بنویسید
        https://netparadis.com/?s=api

        پاسخ
  7. سامان ۲۲ شهریور ۱۳۹۷

    سلام و خسته نباشید . من یک سوال دارم اگه جواب بدید ممنون میشم . فرض کنید یک برنامه html ای دارم . اگر بخوام کاربری که از این برنامه استفاده میکنه صفحه را بصورت فول اسکرین ببینه و اصلا متوجه نشه که برنامه با چی نوشته شده آیا راهی هست که بتونیم برای آن پیاده کنیم ؟ میدونم که دکمه f11 صفحه را fullscreen میکنه ولی میتوانم از آن استفاده کنم . یا لااقل بشه که وقتی برنامه بالا میاد برنامه جاوااسکریپت یک command ای داشته باشه که کار f11 را انجام بده ؟ ممنون از شما

    پاسخ
    1. حسن شفیعی ۲۲ شهریور ۱۳۹۷

      سلام . ممنون . بطور پیشفرض با لود صفحه این مورد قابل انجام نیست چرا که مرورگرها بنابر دلایل امنیتی امکان انجام این مورد رو به ما نمیدن ولی با کلیک یا انجام یک رویداد دیگر میتونید با استفاده از RequestFullscreen() در js روی المنت اصلی این کار رو انجام بدید.
      همچنین این آموزش رو هم میتونید مطالعه کنید
      https://www.sitepoint.com/html5-full-screen-api

      موفق باشید.

      پاسخ
  8. سامان ۱۸ شهریور ۱۳۹۷

    سلام و تشکر از اینکه پاسخ دادید و مشکل من هم رفع شد . یک سوالی دارم اگر راهنمائی کنین ممنون میشم .فرض کنید بخواهیم برای مبادله و جابجائی دیتا با سرور , از سوکت استفاده نکنیم . من یک کار و آزمایش ساده انجام دادم و آن اینکه یک صفحه ساده html حاوی یک فرم با چندین input در آن نوشتم و که با submit کردن فرم و آدرس سرور که به آن میدهیم(در قسمت action) داده ها را به هاست منتقل کرده و هاست هم جواب میدهد و من انرا روی صفحه مشاهده میکنم . همین دیتا را اگر بخواهم با ajax به هاست بفرستم جواب نمیده . از کد هم مطمئنم . آنچه که در url مشاهده میکنیم در دو حالت فوق یکسان هستش . چرا سرور به یکی جواب میده و به دیگری جواب نمیده .

    پاسخ
    1. حسن شفیعی ۱۸ شهریور ۱۳۹۷

      سلام . شما نمیتونید درخواست ajax رو بین دوتا دامنه مختلف منتقل کنید مگر اینکه قابلیت cross-domain رو فعال کنید که با htaccess یا ارسال هدر قابل انجام است.
      https://enable-cors.org/


      header("Access-Control-Allow-Origin: *");

      به جای ستاره هم میتونید دامنه رو مشخص کنید که احیانا باگی این وسط پیش نیاد.(که خب بعد از تست نهایی و اطمینان از کار کردن این مورد ست کردن دامنه های ولید رو روی نسخه production اپ خود انجام بدید)

      همچنین datatype نوع jsonp رو هم تست کنید https://remysharp.com/2007/10/08/what-is-jsonp

      موفق باشید.

      پاسخ
      1. سامان ۱۸ شهریور ۱۳۹۷

        ممنون جناب مهندس از راهنمائیتون . مشکلم حل شد

        پاسخ
  9. سامان ۱۵ شهریور ۱۳۹۷

    سلام و ممنون از اطلاعاتی که دادید . من تمام کارهائی که گفتید را انجام دادم و در نهایت با خطائی که خودتون گفتید مواجه شدم . شماره پورت را هم هر چی عوض کردم باز همون خطا را میده . مشکل کجاست ؟ تشکر از شما

    پاسخ
    1. حسن شفیعی ۱۵ شهریور ۱۳۹۷

      سلام . خوشحالم که مفید واقع شده. مطمینا این مشکل به خاطر پورت است که بهتره از پورت های ۹۰۰۰ به بعد مثلا ۹۰۰۱ استفاده و تست کنید
      با دستورس netstat -a در cmd ویندوز میتونید پورت های باز و بسته کانکشن فعلی رو بررسی کنید

      موفق باشید.

      پاسخ
  10. آرمان ۵ آذر ۱۳۹۶

    دمتون گرم، عالی

    پاسخ
    1. حسن شفیعی ۵ آذر ۱۳۹۶

      خواهش می کنم . خوشحالم که مفید واقع شده
      موفق باشید

      پاسخ
دوره های آموزشی