برنامه نویسی سوکت (Socket) با PHP

۱۳۹۰/۱۲/۲۳

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

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

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

باید در ابتدا ذکر کنم که این مقاله مقدماتی بوده و در درجه اول برای توسعه دهندگان وب که علاقه مند به گسترش دانش پی اچ پی خود در محدوده برنامه نویسی شبکه هستند میباشد.
پی اچ پی یک مجموعه نسبتا جامعی از توابع برای ایجاد و دستکاری ارتباطات سوکتی به همراه دارد.با این وجود این قابلیت به طور پیش فرض فعال نیس در نتیجه لازم است پارامتر “–enable-sockets” را فعال کنید.

خب بهتره با یه مثال ساده شروع کنیم که TCPسرور یک رشته را به عنوان ورودی میگیرد و آنرا معکوس کرده و به کلاینت بر میگرداند:


// متغییر هایی دلخواه و مورد نیاز تعریف میکنیم
$host = "192.168.1.99";
$port = 1234;
//  timeout نداریم!
set_time_limit(0);
// یک سوکت میسازیم
$socket = socket_create(AF_INET, SOCK_STREAM, 0) or die("Could not create
socketn");
// الحاق سوکت به پورت
$result = socket_bind($socket, $host, $port) or die("Could not bind to
socketn");
// شروع انتظار برای ارتباط
$result = socket_listen($socket, 3) or die("Could not set up socket
listenern");
// پذیرفتن ارتباط ورودی
// spawn کردن سوکت برای مدیریت ارتباط
$spawn = socket_accept($socket) or die("Could not accept incoming
connectionn");
// خواندن ورودی کلاینت
$input = socket_read($spawn, 1024) or die("Could not read inputn");
// پاک سازی ورودی
$input = trim($input);
// معکوس کردن ورودی کلاینت و باز پس فرستادن
$output = strrev($input) . "n";
socket_write($spawn, $output, strlen ($output)) or die("Could not write
outputn");
// بستن سوکت
socket_close($spawn);
socket_close($socket);
?>

این کد تا حدودی پیچیده به نظر میاد پس توضیحاتی به ترتیب کد داده میشود:


۱-در گام اول یک جفت متغیر برای نگه داری اطلاعات IP آدرس و پورت که بر روی سرور سوکت، اجرا خواهند شد را تعریف میکنیم.می توانید هر پورتی از محدوده ۱ تا ۶۵۵۳۵ بر روی سرور خود تنظیم و استفاده کنید به شرطیکه پورت قبل شما در حال استفاده نباشد.

$host = "192.168.1.99";
$port = 1234;

2-از آنجایی که کارمان با سرور است این ایده نیز خوب است که از تابع set_time_limit() برای مطمئن شدن از اینکه پی اچ پی تایم اوت نشده و یا زمانیکه برای اتصالهای ورودی کلاینت صبر میکنیم die() نشده باشد،استفاده کنیم.

set_time_limit(0);

3-با این مقدمات حال وقت آن است که با تابع socket_create() یک سوکت ایجاد کنیم،این تابع یک handle بر میگرداند که در بسیاری از فراخوانی های توابع دیگر مورد استفاده قرار میگرد.

$socket = socket_create(AF_INET, SOCK_STREAM, 0) or die("Could not create
socketn");

4- زمانیکه یک کنترلر یا هندل برای سوکتی ساخته شد در گام بعدی آنرا به یک پورت یا آدرس مشخص الحاق یا “bind” میکنیم که از طریق تابع socket_bind() این کار انجام میشود.

$result = socket_bind($socket, $host, $port) or die("Could not bind to
socketn");

5-با استفاده از سوکت ایجاد و متصل شده به یک پورت،زمان آن است منتظر ارتباطهای دریافتی باشیم یا به عبارتی گوش دهیم(Listen) .پی اچ پی به شما اجازه میدهد تا سوکت را توسط تابع socket_listen() به عنوان گوش دهنده تنظیم کنید همچنین به شما اجازه میدهد تعداد ارتباطاتِ صف شده به عنوان پارامتر دوم را تعیین کنید.

$result = socket_listen($socket, 3) or die("Could not set up socket
listenern");

6-در این مرحله،سرورتان اساسا کاری انجام نمیده،منتظر ارتباطهای کلاینتی دریافتی می ماند،به محض اینکه ارتباط کلاینتی دریافت شود،تابع socket_accept() وارد عمل میشود.درخواست ارتباط را میپذیرد و و سوکت های فرزند را تخم ریزی کرده(spawn) و پیغامهای بین سرور و کلاینت را کنترل میکند.

$spawn = socket_accept($socket) or die("Could not accept incoming
connectionn");

7-با توجه به اینکه اتصال برقرار شده است،حال سرور منتظر می ماند که کلاینت یک ورودی ارسال کند. این ورودی توسط تابع socket_read() خوانده میشود و به متغییر $input ریخته میشود.

$input = socket_read($spawn, 1024) or die("Could not read inputn");

پارامتر دوم socket_read() مقدار بایت لازم برای خواندن از ورودی را مشخص میکند. میتوانید برای محدود کردن حجم خواندن جریان داده ها از کلاینت از این پارامتر استفاده کنید.

نکته: تابع socket_read() خواندن داده ها از کلاینت را تا زمانی که با یک بازگشت نورد(n)، tab (t) یا یک کاراکتر مواجه شود ادامه میدهد.این کرکتر به عنوان کارکتر پایانِ ورودی تلقی میشود.

۸-حال سرور باید اطلاعات ارسال شده توسط کلاینت را پردازش کند،در این مثال،این پردازش فقط شامل معکوس کردن رشته ورودی و ارسال آن به کلاینت است،این کار توسط تابع socket_write() انجام میشود.

$output = strrev($input) . "n";
socket_write($spawn, $output, strlen ($output)) or die("Could not write
outputn");

تابع socket_write() به سه پارامتر نیاز دارد:یک مرجع برای سوکت،رشته ای برای نوشتن در داخل آن،و مقدار بایت نوشته شده.
۹-هنگامی که خروجی به کلاینت فرستاده شد،هر دو سوکت ایجاد شده توسط تابع socket_close() بسته میشوند.

socket_close($spawn);
socket_close($socket);

15 دیدگاه در “برنامه نویسی سوکت (Socket) با PHP

  1. تا زمانی که thread نداشته باشیم توی PHP، نوشتن سوکت‌سرور زیاد ارزش‌مند نیست!

    درسته تعداد کلاینت‌ها رو می‌شه مشخص کرد، اما در حین انجام پروسه، تا زمان رسیدن به socket_accept درخواست‌ها توی صف گیر می‌کنه و کافیه این پروسه کمی طول بکشه و زمانی که داره پروسه‌ی درخواست دوم انجام می‌شه، نمی‌تونی کار درخواست اول رو انجام بدی (اگر نیاز باشه کاری انجام بشه!)
    البته خیلی سخت می‌شه با مدیریت پروسس‌ها، threadها رو شبیه‌سازی کرد.

    موفق باشید.

    پاسخ
  2. میشه باهاش کارهای ساده ای انجام داد، ولی یه کار جدی نه. مثلا من ازش استفاده کردم برای یک ربات IRC ساده.
    ممنون بابت پست.

    پاسخ
  3. ممنون مرتضی جان
    خوب بود
    اصولن پی اچ پی برای این کارا خیلی مناسب نیست
    ولی خوب تا حدودی می تونه رفع نیاز بکنه برای استقلالش و این خوبه
    از امید و فرود هم ممنون

    پاسخ
  4. ممنونم بابت این پست.ادامشو نمیذارید؟
    من میخوام برنامه ی چت رو بنویسم.کمک لازم دارم.ممنون میشم در این رابطه راهنمایی کنید.

    پاسخ
    • چرا دوست عزیز ولی فکر نکنم به این زودی :-)
      در رابطه با کمک هم ایمیل بزنید آخه واسه خودم هم همچین برنامه ای لازم شده

      پاسخ
  5. بسیار سپاسگزارم از شما دوست گرانقدر. برای شما آرزوی پیروزی و کامروایی دارم. بسیار خوب بود.

    پاسخ
  6. تا اونجایی که من میدونم در پی اچ پی امکان thread programming هست (پاسیکس)
    خیلی ممنون مرتضی عزیز

    پاسخ

پاسخ دهید

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

شما می‌توانید از این دستورات HTML استفاده کنید: