تابع stream_socket_get_name() در PHP
در توسعه شبکهای با PHP، گاهی لازم است آدرس طرف مقابل (کلاینت) یا آدرس محلی یک اتصال را به دست بیاوریم. برای این منظور PHP تابع stream_socket_get_name() را فراهم میکند که روی streamهای مبتنی بر سوکت کار میکند. این تابع ساده اما کاربردی در لاگگذاری، کنترل دسترسی و نمایش اطلاعات اتصال بسیار مفید است.
امضای تابع و پارامترها
امضای تابع به صورت زیر است:
stream_socket_get_name(resource $stream, bool $want_peer): string|falseتوضیح پارامترها:
- $stream — یک resource متعلق به stream که از توابعی مانند
stream_socket_server،stream_socket_acceptیاstream_socket_clientبرمیگردد. - $want_peer — اگر
trueباشد، نام (آدرس) طرف مقابل (peer) بازگردانده میشود؛ اگرfalseباشد، نام محلی (local) برگردانده میشود.
خروجی تابع
در صورت موفقیت تابع یک رشته برمیگرداند و در صورت خطا مقدار false. فرمت رشته معمولاً برای TCP/UDP به شکل IP:PORT است و برای Unix domain sockets مسیر فایل نمایان میشود. برای IPv6 ممکن است خروجی به صورت [::1]:PORT باشد.
مثال عملی — سرور ساده با ثبت آدرس کلاینت
<?php
$server = stream_socket_server("tcp://127.0.0.1:9000", $errno, $errstr);
if (!$server) {
die("Unable to create server: $errstr ($errno)n");
}
while ($conn = @stream_socket_accept($server)) {
$peer = stream_socket_get_name($conn, true); // آدرس کلاینت
$local = stream_socket_get_name($conn, false); // آدرس محلی
echo "Connected: peer=$peer, local=$localn";
fwrite($conn, "Hello from servern");
fclose($conn);
}
?>توضیح: این کد یک سرور TCP روی پورت 9000 ایجاد میکند. پس از پذیرش هر اتصال، با استفاده از stream_socket_get_name هم آدرس کلاینت (peer) و هم آدرس محلی را میگیرد و سپس پیامی برای کلاینت میفرستد. اگر ایجاد سرور ناموفق باشد پیام خطا نمایش داده میشود.
مثال کلاینت — مشاهده آدرس محلی و سرور متصلشده
<?php
$client = stream_socket_client("tcp://127.0.0.1:9000", $errno, $errstr, 5);
if (!$client) {
die("Unable to connect: $errstr ($errno)n");
}
$remote = stream_socket_get_name($client, true); // آدرس سرور (peer)
$local = stream_socket_get_name($client, false); // آدرس محلی (local)
echo "Remote: $remotenLocal: $localn";
echo fgets($client);
fclose($client);
?>توضیح: این مثال یک کلاینت میسازد که به سرور محلی روی پورت 9000 متصل میشود. سپس با stream_socket_get_name آدرس سرور و آدرس محلی را نمایش میدهد. این اطلاعات برای لاگ و تشخیص پورتهای ephemeral مفید است.
نکات مربوط به IPv6 و پردازش دقیق آدرس و پورت
در برخورد با IPv6 باید مراقب باشید چون آدرسها خود شامل : هستند. خروجی معمولاً به صورت [IPv6]:PORT یا گاهی بدون کروشه خواهد بود. برای جدا کردن آدرس از پورت از روش امن زیر استفاده کنید:
<?php
function splitAddressPort(string $name): array {
// name ممکن است: 127.0.0.1:1234 یا [::1]:1234 یا unix:///path
if (strpos($name, 'unix:') === 0 || strpos($name, '/')) {
return [$name, null]; // مسیر یونیکس یا رشتهای دیگر
}
if (strpos($name, '[') === 0) {
// [IPv6]:PORT
$pos = strpos($name, ']');
$ip = substr($name, 1, $pos - 1);
$port = substr($name, $pos + 2);
return [$ip, (int)$port];
}
// IPv4 or plain host:port
$pos = strrpos($name, ':');
if ($pos !== false) {
$ip = substr($name, 0, $pos);
$port = substr($name, $pos + 1);
return [$ip, (int)$port];
}
return [$name, null];
}توضیح: این تابع رشته بازگشتی از stream_socket_get_name را تجزیه کرده و آدرس و پورت را به صورت جداگانه برمیگرداند. ابتدا حالتهای یونیکس و IPv6 در نظر گرفته میشوند و سپس برای حالتهای IPv4 یا host:port از آخرین دو-نقطه استفاده میشود تا با IPv6 تداخل نکند.
موارد استفاده عملی و نکات امنیتی
- لاگگذاری آدرس کلاینت برای بررسی ترافیک و اشکالزدایی.
- محدودسازی دسترسی بر اساس آدرس آیپی (ACL) قبل از پردازش درخواستها.
- استفاده در تستها برای مشاهده پورتهای ephemeral که سیستم عامل تخصیص میدهد.
- در UDP: اگر سوکت به صورت connectionless باشد، ممکن است آدرس peer تنها پس از دریافت بسته مشخص شود یا اطلاعات لازم را نداشته باشید.
مقایسه با توابع مرتبط
| تابع | کاربرد |
|---|---|
| stream_socket_get_name() | دریافت نام محلی یا آدرس peer برای streamهای مبتنی بر سوکت |
| socket_getpeername() | همان کار برای منابع ext-sockets (سویکتهای سطح پایین) |
| stream_socket_enable_crypto() | فعالسازی SSL/TLS روی streamها (ممکن است آدرس تغییری نکند ولی نحوه دسترسی متفاوت است) |
خطاها و نکات عملیاتی
- اگر stream معتبر نباشد یا اتصال برقرار نشده باشد، تابع
falseبرمیگرداند. - در صورتی که دسترسی به اطلاعات سوکت محدود شده باشد یا سوکت در حالت خاصی باشد، ممکن است اطلاعات کامل را دریافت نکنید.
- برای UDP و سوکتهای connectionless ممکن است تنها پس از
stream_socket_recvfromآدرس peer واضح شود.
خلاصه و توصیههای نهایی
تابع stream_socket_get_name() یک ابزار ساده و قدرتمند برای بهدست آوردن آدرسهای مرتبط با streamهای مبتنی بر سوکت در PHP است. با توجه به تفاوتهای IPv4/IPv6 و یونیکس سوکتها، بهتر است همیشه خروجی را بهصورت امن پارس کنید و در صورت نیاز از بررسیهای اضافی برای امنیت و لاگبرداری استفاده نمایید.
در پروژههای واقعی، ترکیب این تابع با منطق احراز هویت، لیست سیاه/سفید و ثبت رویدادها میتواند به بهبود امنیت و قابلیت ردیابی کمک کند.
آیا این مطلب برای شما مفید بود ؟



