تابع socket_get_status() در PHP
تابع socket_get_status() در PHP یکی از ابزارهای مفید برای بررسی وضعیت یک منبع (stream) است. این تابع اطلاعاتی دربارهٔ وضعیت اتصال، خواندهنشدهها، وضعیت تایماوت و مشخصات استریم برمیگرداند. اگر با توابعی مثل fsockopen، pfsockopen، stream_socket_client یا حتی fopen روی منابع شبکه کار میکنید، این تابع به شما کمک میکند رفتار اتصال را مانیتور کنید.
زمان و دلیل استفاده
- تشخیص اینکه آیا اتصال قطع (EOF) شده است یا خیر.
- بررسی اینکه اتصال در حالت بلاک هست یا نانبلاک.
- پیدا کردن تعداد بایتهای خواندهنشده در بافر داخلی.
- شناسایی وضعیت تایماوت پس از فراخوانی توابع خواندن/نوشتن.
- دریافت متادیتا دربارهٔ نوع استریم، مود و URI مرتبط.
امضای تابع و مقدار بازگشتی
امضای تابع به شکل زیر است:
array socket_get_status(resource $stream)این تابع یک آرایهٔ انجمنی (associative array) برمیگرداند که شامل کلیدهای زیر است (مشابه خروجی stream_get_meta_data):
| کلید | شرح |
|---|---|
| timed_out | بولی؛ آیا اتصال دچار تایماوت شده است یا خیر. |
| blocked | بولی؛ آیا استریم در حالت بلوک (blocking) است یا نانبلاک. |
| eof | بولی؛ آیا به انتهای فایل/اتصال (EOF) رسیدهایم. |
| unread_bytes | عدد صحیح؛ تعداد بایتهای موجود در بافر داخلی که هنوز خوانده نشدهاند. |
| stream_type | رشته؛ نوع استریم مانند “tcp_socket/ssl” |
| wrapper_type | رشته؛ نوع wrapper (مثلاً “tcp”) برای توصیف wrapper استفادهشده. |
| wrapper_data | مقدار؛ اطلاعات اضافه وابسته به wrapper (معمولاً null یا آرایه). |
| mode | رشته؛ مد باز کردن استریم (مثلاً “r+”, “w”). |
| seekable | بولی؛ آیا استریم قابل seek است یا خیر. |
| uri | رشته؛ آدرس یا URI منبع باز. |
نمونه کد: بررسی وضعیت یک اتصال TCP ساده
<?php
$host = 'example.com';
$port = 80;
// ایجاد اتصال TCP با fsockopen
$fp = fsockopen($host, $port, $errno, $errstr, 5);
if (!$fp) {
echo "Error: $errstr ($errno)n";
exit;
}
// ارسال یک درخواست HTTP ساده
fwrite($fp, "GET / HTTP/1.1rnHost: $hostrnConnection: closernrn");
// بررسی وضعیت بلافاصله بعد از نوشتن
$status = socket_get_status($fp);
print_r($status);
// خواندن پاسخ مرحلهای تا انتها
while (!feof($fp)) {
$line = fgets($fp, 1024);
echo $line;
// بررسی وضعیت در هر دور حلقه
$s = socket_get_status($fp);
if ($s['timed_out']) {
echo "Connection timed outn";
break;
}
}
fclose($fp);
?>در این مثال ابتدا اتصال TCP به پوستهٔ 80 برقرار میشود، سپس یک درخواست HTTP ساده فرستاده میشود. تابع socket_get_status() پس از نوشتن و درون حلقهٔ خواندن صدا زده میشود تا وضعیت اتصال (مثل تایماوت یا EOF) بررسی شود. این روش مخصوصاً در اسکریپتهایی که نیاز به مانیتورینگ دقیق اتصال دارند مفید است.
نمونه واقعی: تشخیص EOF و unread_bytes
<?php
$fp = stream_socket_client("tcp://example.com:80", $errno, $errstr, 5);
if (!$fp) exit("Connection failed");
stream_set_timeout($fp, 2); // تنظیم تایماوت خواندن
fwrite($fp, "GET / HTTP/1.1rnHost: example.comrnConnection: closernrn");
$status = socket_get_status($fp);
echo "Unread bytes initially: " . $status['unread_bytes'] . "n";
while (!feof($fp)) {
$chunk = fread($fp, 512);
echo $chunk;
$status = socket_get_status($fp);
echo "EOF: " . ($status['eof'] ? 'yes' : 'no') . ", Timed out: " . ($status['timed_out'] ? 'yes' : 'no') . "n";
}
fclose($fp);
?>اینجا نشان میدهیم که چگونه مقدار unread_bytes و پرچمهای eof و timed_out میتوانند به تصمیمگیری در زمان خواندن دادهها کمک کنند. توجه کنید که مقدار unread_bytes همیشه دقیقاً آنچه در شبکه منتظر است را نشان نمیدهد بلکه مربوط به بافر داخلی PHP است.
نکات و بهترین شیوهها
- برای کنترل دقیقتر تایماوت از توابع stream_set_timeout و stream_select استفاده کنید؛ socket_get_status فقط وضعیت فعلی را گزارش میدهد.
- در محیطهای پرمصرف (high concurrency) برای جلوگیری از بلوک شدن برنامه از حالت نانبلاک (non-blocking) یا select/poll استفاده کنید.
- نکتهٔ مهم: socket_get_status برای منابع stream کار میکند؛ اگر از extension native sockets (مثل socket_create و socket_recv) استفاده میکنید، باید از توابع مرتبط با آن اکستنشن بهره ببرید (مثلاً socket_getsockname یا socket_last_error).
- در صورت استفاده از سوکتهای پایدار (persistent sockets با pfsockopen)، مراقب وضعیت wrapper_data و uri باشید زیرا ممکن است اطلاعاتی دربارهٔ نگهداری اتصال وجود داشته باشد.
مقایسه با توابع مشابه
تابع stream_get_meta_data() خروجی بسیار مشابهی میدهد و در بسیاری از اسناد بهعنوان معادل یا جایگزین ذکر شده است. اگر نیاز به بررسی سطح پایینتر یا مدیریت خطاهای شبکه دارید، از مجموعه توابع socket_* (extension sockets) همراه با socket_select و socket_recv استفاده کنید.
خلاصه و جمعبندی
تابع socket_get_status() ابزاری ساده ولی کارا برای دریافت متادیتای استریمها در PHP است. این تابع اطلاعات مهمی مثل تایماوت، EOF، تعداد بایتهای خواندهنشده و نوع استریم را برمیگرداند که برای تشخیص وضعیت اتصال و کنترل جریان دادهها مفید است. برای کاربردهای حساس به عملکرد یا نیازمند کنترل همزمانی بیشتر از ترکیبهای غیربلاک و select/poll استفاده کنید.
در صورت نیاز به نمونههای پیشرفتهتر یا توضیح دربارهٔ تفاوت با توابع sockets extension بفرمایید تا مثالهای عملیتر و بهینهسازی شده ارائه کنم.
آیا این مطلب برای شما مفید بود ؟



