getservbyname(string $service, string $protocol): int|false
此函數用於通過服務名和協議名查詢對應的端口號。例如,HTTP 服務通常使用TCP 協議並監聽80 端口。
$port = getservbyname('http', 'tcp');
echo $port; // 輸出: 80
getprotobyname(string $name): int|false
此函數用於根據協議名(如"tcp"、"udp")獲取協議編號。例如:
$proto = getprotobyname('tcp');
echo $proto; // 輸出: 6
當我們需要連接某個網絡服務時,往往不僅需要知道服務的端口號,還要知道使用的協議編號。例如,在使用socket_create()和socket_connect()建立連接時,需要提供協議編號作為參數之一。
結合使用兩個函數可以如下操作:
$service = 'http';
$protocol = 'tcp';
$port = getservbyname($service, $protocol);
$proto = getprotobyname($protocol);
if ($port === false || $proto === false) {
die("無法解析服務或協議\n");
}
echo "服務 '{$service}' 使用端口: {$port}\n";
echo "協定 '{$protocol}' 的編號是: {$proto}\n";
下面是一個簡單的使用這兩個函數創建TCP 連接的例子:
$service = 'http';
$protocol = 'tcp';
$host = 'gitbox.net';
$port = getservbyname($service, $protocol);
$proto = getprotobyname($protocol);
if ($port === false || $proto === false) {
die("服務或協定无法识别\n");
}
$socket = socket_create(AF_INET, SOCK_STREAM, $proto);
if ($socket === false) {
die("無法創建 socket: " . socket_strerror(socket_last_error()) . "\n");
}
$result = socket_connect($socket, $host, $port);
if ($result === false) {
die("無法連接到 {$host}:{$port} - " . socket_strerror(socket_last_error($socket)) . "\n");
}
echo "成功連接到 {$host}:{$port},使用協定编号 {$proto}\n";
socket_close($socket);
在這個示例中,我們利用getservbyname()獲取HTTP 對應的端口80,利用getprotobyname()獲取TCP 協議編號6,然後創建並連接一個TCP socket 到gitbox.net的80 端口。
這兩個函數依賴系統的服務和協議定義文件,如/etc/ services和/etc/ protocols ,如果定義不完整可能導致解析失敗。
使用這些函數的結果應始終進行錯誤判斷,避免運行時出錯。
這些函數是對C 語言中getservbyname 和getprotobyname 的簡單封裝,對於熟悉底層socket 編程的用戶非常友好。